1 /*      This program displays functional EPI of the form 64x64 up to 512x512
2         in X11 windows. Keys and subWindow are added. The ar is malloc().
3         It uses 8 or 12 bitplanes and own solid color map, or any RGB mode.
4         Extras: image marker, continuous X,Y position.
5         EPI part based on Eric C. Wong program fd_multi.c .
6         Added rectangular box and time average 11-12-2002 AJ.
7         Andre Jesmanowicz, 4-03-2008, Medical College of Wisconsin. */
8 
9 #define CONTRAST_CHANGE_STEP 15000/* larger step => slower change AJ 11.1.96 */
10 
11 #define ASC_NUL '\0'
12 #undef  FILL_WITH_CYAN
13 
14 #define MAIN
15 
16 /***---------------- additions for use of array of MRI_IMAGE --------------***/
17 
18 #include "FD2_inc.c"  /* 16 Jul 2007 -- to avoid use of mrilib */
19 
20 #include "overfim.h"
21 #include "pcor.h"
22 
23 #define INC_ALLIM 8
24 
25 int dim_allim = 0 ;
26 
27 MRI_IMAGE ** allim   = NULL ;
28 MRI_IMAGE ** t_allim = NULL ;  /* tmp pointer of allim when FFT done AJJ */
29 
30 MRI_IMAGE * im_tmp_ar = NULL ;  /* the working array for displays, etc */
31 short * tmp_ar = NULL ;
32 #define SIZE_tmp_ar(n) im_tmp_ar->nx = im_tmp_ar->ny = (n)
33 
34 short * nowim = NULL ;
35 int     nowsize ;
36 
37 #define SAR(k)   MRI_SHORT_PTR(allim[k])   /* get pointer to data for image k */
38 #define T_SAR(k) MRI_SHORT_PTR(t_allim[k]) /* pointer to temp data of im k */
39 #define SIZ(k) (allim[k]->nx * allim[k]->ny)
40 #define DIM(k) (allim[k]->nx)
41 
42 void add_extra_image() ;
43 
44 MRI_IMAGE * RWC_pcim = NULL , * RWC_alpim = NULL ;
45 
46 int RWC_autoscale = 0 ;  /* to autoscale image intensities */
47 int RWC_overhide  = 0 ;  /* to hide overlay in image */
48 int RWC_framehide = 0 ;  /* to hide frame in image */
49 int RWC_checker   = 0 ;  /* to checkerboard or not to checkerboard */
50 int RWC_groupbase = 0 ;  /* to use a group baseline or not */
51 int AJ_base = 0;         /* to set base to zero when group baseline is on */
52 
53 /* additions for use of MCW logo */
54 
55 #ifdef USE_MCW
56    extern int mcw_load() ;  /* prototype */
57    extern short mcw_im[] ;  /* image array */
58 #include <unistd.h>
59 #endif
60 
61 /***-----------------------------------------------------------------------***/
62 
63 #include <stdio.h>
64 #include <math.h>
65 #include <ctype.h>
66 #include <sys/types.h>
67 #include <sys/stat.h>
68 #ifdef   SYSV
69 #include <sys/fcntl.h>
70 #endif
71 
72 #include <X11/Xos.h>
73 #include <X11/Xlib.h>
74 #include <X11/Xutil.h>
75 #include <X11/cursorfont.h>
76 #include <X11/keysym.h>
77 #include <sys/ioctl.h>
78 
79 #define IM_HEIGHT 256
80 #define IM_MAX_H 512
81 int     im_height = IM_HEIGHT;        // minimum image size
82 #define NUM_STD_COLORS 16
83 #define IM_ARR    (IM_MAX_H*IM_MAX_H) // include 512x512 images too
84 #define NCOLORS   808  /* default # of colors */
85 #define MCOLORS   856  /* maximum # of colors: NCOLORS + NUM_STD_COLORS (16) */
86                        /*                    + MAX_EXTRA_COLORS (32) */
87 #define N_SPCTR   240                 /* def degree of color spectrum */
88 #define M_SP_COL  360                 /* max degree of color spectrum */
89 #define BELT_W    24                  /* reference color belt width */
90 #define BELT_S    3                   /* color belt sides width */
91 #define BELT_A    (BELT_W*IM_MAX_H)
92 #define NF_MAX    10000               /* Max # of files */
93 #define STR_L     256                 /* Max length of string */
94 
95 #define COL_MIN    0
96 #define MAX_WIDTH  2048  /* Never less then screen max_width */
97 
98 #define EPX1      64                   /* List of supported EPI image sizes */
99 #define EPY1      64                   /* Each triple is: */
100 #define EPS1      (2*EPX1*EPY1)        /* xsize, ysize, filesize */
101 
102 #define EPX2      128
103 #define EPY2      128
104 #define EPS2      (2*EPX2*EPY2)
105 
106 #define EPX3      256
107 #define EPY3      256
108 #define EPS3      (2*EPX3*EPY3)
109 
110 #define EPX4      32
111 #define EPY4      32
112 #define EPS4      (2*EPX4*EPY4)
113 
114 #define EPX5      512
115 #define EPY5      512
116 #define EPS5      (2*EPX5*EPY5)
117 
118 #if 0                                 // old stuff for max size 256x256 4.03.2008
119   #define OFFSET    (28*IM_HEIGHT)       /* offset to data in 145408 bytes im */
120   #define H_SIZE    (OFFSET+IM_ARR)      // 256x256 image with header
121 #endif
122 
123 int     gx_max =  512;                 /* Horizontal size of graph window */
124 int     gy_max =  512;                 /* Vertical size of graph window */
125 #define GR_DLX    3                    /* Horizontal delta to right edge */
126 #define GT_DLY    21                   /* Vertical delta to top edge */
127 #define GL_DLX    50                   /* Horizontal delta to left edge */
128 #define GB_DLY    50                   /* Vertical delta to bottom edge */
129 #define MAT_MAX   25                   /* Maximum array size of graphs */
130 #define GRID_NUM  8                    /* Maximum grid index */
131 #define COL_NUM   5                    /* Number of colors */
132 #define GRID_COEF 50.                  /* alternate for slow scannings */
133 
134 /**************************************************************************/
135 
136 #define min_max_col(a) ((a) < (256) ? (256) : ((a) > (65280) ? (65280) : (a)))
137 #define min(a,b) ((a) < (b) ? (a) : (b))
138 #define max(a,b) ((a) > (b) ? (a) : (b))
139 
140 /* keys (small subwindows) stuff ----- vvvvvvvvv ------  AJ */
141 
142 #define KFONT     "lucidasanstypewriter-bold-12"  /* defaults */
143 #define TFONT     "pellucidatypewriter10"
144 #define PADDINGW  3
145 #define PADDINGH  5
146 #define KEY_1_Y   50
147 
148 /* fonts to try if the defaults fail */
149 
150 static char * tfont ,
151             * tfont_hopefuls[] = {
152                "filled-in-by-default" ,
153                "lucidasanstypewriter-10" ,
154                "-adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1" ,
155                "-misc-fixed-medium-r-normal--13-100-100-100-c-70-iso8859-1" ,
156                "7x14" , "6x13" , "vtsingle" , "fixed" ,
157                NULL } ;
158 
159 struct _key {
160            char   *st;
161            int    code;
162            int    (*fun)();
163            Window wid;
164            short  x,y,width,height;
165   unsigned long   fore,back; // long is OK here AJJ
166            void   (*func)();
167             };
168 
169 struct _key *key;
170 
171 #define N_KEYS 21
172 #define LAST_K 8    /* RWC: incremented this to put FIM key in */
173 
174 #define kROT   0
175 #define kHLP   1
176 #define kAVR   2
177 #define kDIF   3
178 #define kSIG   4
179 #define kFFT   5
180 #define kSCA   6
181 #define kFIM   7    /* RWC: put this in as new permanent button */
182 #define kNRM   8
183 #define kAV1   9
184 #define kAV2  10
185 #define kIR1  11
186 #define kIR2  12
187 
188 #define kFI1  13   /* RWC: new buttons when FIM key is pressed */
189 #define kFI2  14
190 #define kFI3  15   /* the POWER KEY (named by Lloyd Estkowski) */
191 
192 #define kFT1  16
193 #define kFT2  17
194 #define kFT3  18
195 
196 #define kSC1  19
197 #define kSC2  20
198 
199 int  Ims_rot(), Im_help(), Im_diff(), SCA_action(), Ref_im1(), Ref_im2();
200 int  Im_Aver(), Im_norm(), Av_im1(), Av_im2(), Smooth_line();
201 
202 #define FFT_first_key kFT1
203 #define FFT_last_key  kFT3
204 
205 int  FFT_action(), FFT_selection();
206 int  FFT_pressed = 0;
207 int  FT1_pressed = 0, FT2_stat = 0, FT3_stat = 0;
208 int  z_im1=0, z_imL=0;
209 char *key_kFFT_FFT   = "FFT" ;
210 char *key_kFFT_noFT  = "noFT";
211 char *key_kFT1[2]    = {"edit", "end"};
212 char *key_kFT2[4]    = {" FT ", "0..0", "from", " to "};
213 char *key_kFT3[3]    = {"    ", "i FT", "zero"};
214 
215 #define SCA_first_key kSC1
216 #define SCA_last_key  kSC2
217 int   SCA_selection();
218 int   SCA_pressed = 0;
219 char  *key_kSCA[2]  = {"Scale", "ScEnd"};
220 float SCA_ref_val = -1.;
221 float SCA_ratio = 0.;
222 
223 #define FIM_first_key kFI1
224 #define FIM_last_key  kFI3
225 
226 int  FIM_action() , FIM_selection() ;
227 int  FIM_pressed = 0 , FIM_modified = 0 ;
228 
229 char *FIM_selection_name[FIM_last_key-FIM_first_key+1] =
230       { "Correlation Coefficient Threshold (0..1)"    , /* dialog box labels */
231         "Vector Filename ('!nofim'==none)"            ,
232         NULL                                          /* don't use dialog box */
233       } ;
234 
235 char *key_kFIM_FIM = "FIM" ;
236 char *key_kFIM_GO  = "GO!" ;
237 
238 /*** DFILT stuff has been deactivated -- RWCox July 1995 ***/
239 
240 #define DFILT_NONE   0                 /* no derivative filtering */
241 #define DFILT_TIME   1                 /* temporal mode */
242 #define DFILT_SIGMA  (4.0*0.42466090)  /* FHWM = 4.0 pixels */
243 #define DFILT_THRESH 0.05              /* threshold for using 'fit' */
244 #define DFILT_NREF   3
245 static char * DFILT_fimcode[2] = { "FIM" , "DFIM" } ;
246 static int DFILT_code = DFILT_NONE ;   /* flag to do DFILT */
247 
248 #define MAX_TOTAL_REF (MAX_NUMORT+MAX_POLORT+DFILT_NREF+4)
249 
250 #define LSQ_NONE     0                     /* no Least square remove in graphs */
251 #define LSQ_SUBORT   1                     /* remove Orts but not ideal */
252 #define LSQ_SUBALL   2                     /* remove Orts and Ideal */
253 #define LSQ_FITORT   3                     /* show fit of Orts */
254 #define LSQ_FITALL   4                     /* show fit of Orts and Ideal */
255 #define LSQ_SORFID   5                     /* remove orts, show Ideal fit */
256 
257 #define LSQ_LASTCODE 5
258 
259 #define LSQ_EDIT_NONE -1
260 #define LSQ_EDIT_ORT   1
261 #define LSQ_EDIT_ALL   0
262 
263 static int LSQ_imedit[LSQ_LASTCODE+1] =
264  { LSQ_EDIT_NONE, LSQ_EDIT_ORT, LSQ_EDIT_ALL, LSQ_EDIT_NONE, LSQ_EDIT_NONE, LSQ_EDIT_NONE } ;
265 static char * LSQ_fimcode[LSQ_LASTCODE+1] =
266  { " " , "SUB:ort" , "SUB:all" , "FIT:ort" , "FIT:all" ,"SUB:ort FIT:ideal"} ;
267 static int LSQ_code = LSQ_NONE ;
268 static int LSQ_refcount = 0 ;
269 static time_series * LSQ_ref[MAX_TOTAL_REF] ;
270 static MRI_IMARR *   LSQ_fitim = NULL ;
271 static float * LSQ_fit[MAX_TOTAL_REF] ;
272 
273 #define kFI3_NUM  11   /* number of options on the POWER KEY */
274 
275 char *key_kFI3[kFI3_NUM] = { "ref =pixel ->" ,   /* labels for POWER KEY */
276                              "ref+=pixel ->" ,
277                              "smooth ref ->" ,
278                              "thresh -+  ->" ,
279                              "  NO FIM   ->" ,
280                              "refplt -+  ->" ,
281                              "save ref   ->" ,
282                              "polort -+  ->" ,
283                              "ort = ref  ->" ,
284                              "clear orts ->" ,
285                              "SubFit -+  ->"
286                            } ;
287 
288 char *key_kFI3_help[kFI3_NUM] = { "set reference function = central pixel" ,
289                                   "add central pixel to reference function" ,
290                                   "median (of 3) filter reference function" ,
291                                   "- or + correlation coefficient threshold" ,
292                                   "turn fimming off" ,
293                                   "- or + number of reference function plots" ,
294                                   "save reference function in a file" ,
295                                   "- or + number of polynomial ort functions" ,
296                                   "make current ref an ort instead" ,
297                                   "clear all current ort functions" ,
298                                   "set least squares removal in graphs"
299                                 } ;
300 
301 int kFI3_status       = -1 ;
302 int kFI3_show_ref     = 1 ;
303 int kFI3_refsum_count = 0 ;
304 
305 int kROT_doall      = 1 ;
306 char * key_kROT_all = "Rot" ;
307 char * key_kROT_one = "Rot1" ;
308 
309 struct _key xtkeys[N_KEYS] = { {"Rot"  , kROT, Ims_rot},
310                                {"Help" , kHLP, Im_help},
311                                {"AvIm" , kAVR, Im_Aver},
312                                {"Diff" , kDIF, Im_diff},
313                                {"Smth" , kSIG, Smooth_line},
314                                {"FFT"  , kFFT, FFT_action},
315                                {"Scale", kSCA, SCA_action},
316                                {"FIM"  , kFIM, FIM_action},
317                                {"Norm" , kNRM, Im_norm},
318                                {"Average: from this image" , kAV1 , Av_im1},
319                                {"Average: to this one.   " , kAV2 , Av_im2},
320                                {"Ref. level first image"   , kIR1 , Ref_im1},
321                                {"Ref. level last  image"   , kIR1 , Ref_im2},
322                                {"set threshold"  , kFI1 , FIM_selection},
323                                {"ref/ort file "  , kFI2 , FIM_selection},
324                                {"PUSH BUTTON 3"  , kFI3 , FIM_selection},
325                                {"edit", kFT1 , FFT_selection},
326                                {" FT ", kFT2 , FFT_selection},
327                                {"    ", kFT3 , FFT_selection},
328                                {"Reference  image",  kSC1 , SCA_selection},
329                                {"Scale this image ", kSC2 , SCA_selection}
330                              };
331 
332 char          *kfont, *ffc, *fbc;
333 unsigned long ForeColor, BackColor, FKeyFore, FKeyBack; // long is OK here AJJ
334 XColor        xcsd, xced;
335 XFontStruct   *kfontinfo;
336 Font          keyfont;
337 int           keywide[N_KEYS], minwide, keyhigh;
338 GC            Fkeyigc, Fkeygc;
339 int           invkey    = -1;
340 int           exp_done[N_KEYS+3];   /* GWindow + subWindow +topWindow + keys */
341 short   int   a_rot[IM_ARR], rot_nr = 0, rot_direct , rot_state ;
342 int           sub_W_x, sub_W_y, top_W_x, top_W_y;
343 int           v_point_x = -20, v_point_y = 0;
344 int           diff_im = 0, Im_1, Im_2, im1_done = 0, extra_im = 0;
345 int           avr_grp = 0, Av_1, Av_2, av1_done = 0, Av_length = 1;
346 int           fim_dif = 0, fim_avr = 0, redraw;
347 int           txtW_ON = 0;
348 
349 
350 /* keys (small subwindows) stuff ----- ^^^^^^^^^ ------  AJ */
351 
352 /*---------------------------------------------------------------------------*/
353 #ifdef NEED_DEFS
354 extern double   strtod();
355 char            *malloc();
356 char            *realloc();
357 #endif
358 /*---------------------------------------------------------------------------*/
359 
360 int  STD_colors();
361 
362 void x_events_loop();
363 void Resample();
364 void Put_image();
365 void plot_line();
366 void draw_marker();
367 void scale_up();
368 void scale_down();
369 void mat_up();
370 void mat_down();
371 void init_mat();
372 void grid_up();
373 void grid_down();
374 void print_plot();
375 void redo_graph_window();
376 void window_plane();
377 void graphic_store();
378 void plotx();
379 void plx_txt();
380 void plx_TXT();
381 void subW_TXT();
382 void line_color();
383 void txt_color();
384 void DrawSubWindow();
385 void DrawTopWindow();
386 int  FIM_edit_time_series() ;
387 
388 int  c_f = 0;
389 int    st_8[] = {
390      1,  2,  3,  4,  5,  6,  7,  8,  7,  6,  5,  4,  3,  2,  1,  0,
391      2,  4,  6,  8, 10, 12, 14, 16, 14, 12, 10,  8,  6,  4,  2,  0,
392      3,  6,  9, 12, 15, 18, 21, 24, 21, 18, 15, 12,  9,  6,  3,  0,
393      4,  8, 12, 16, 20, 24, 28, 32, 28, 24, 20, 16, 12,  8,  4,  0,
394      5, 10, 15, 20, 25, 30, 35, 40, 35, 30, 25, 20, 15, 10,  5,  0,
395      6, 12, 18, 24, 30, 36, 42, 48, 42, 36, 30, 24, 18, 12,  6,  0,
396      7, 14, 21, 28, 35, 42, 49, 56, 49, 42, 35, 28, 21, 14,  7,  0,
397      8, 16, 24, 32, 40, 48, 56, 64, 56, 48, 40, 32, 24, 16,  8,  0,
398      7, 14, 21, 28, 35, 42, 49, 56, 49, 42, 35, 28, 21, 14,  7,  0,
399      6, 12, 18, 24, 30, 36, 42, 48, 42, 36, 30, 24, 18, 12,  6,  0,
400      5, 10, 15, 20, 25, 30, 35, 40, 35, 30, 25, 20, 15, 10,  5,  0,
401      4,  8, 12, 16, 20, 24, 28, 32, 28, 24, 20, 16, 12,  8,  4,  0,
402      3,  6,  9, 12, 15, 18, 21, 24, 21, 18, 15, 12,  9,  6,  3,  0,
403      2,  4,  6,  8, 10, 12, 14, 16, 14, 12, 10,  8,  6,  4,  2,  0,
404      1,  2,  3,  4,  5,  6,  7,  8,  7,  6,  5,  4,  3,  2,  1,  0,
405      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 };
406 
407 int    st_4[] = { 1,  2,  3,  4,  3,  2,  1,  0,      /* resampling array */
408                   2,  4,  6,  8,  6,  4,  2,  0,
409                   3,  6,  9, 12,  9,  6,  3,  0,
410                   4,  8, 12, 16, 12,  8,  4,  0,
411                   3,  6,  9, 12,  9,  6,  3,  0,
412                   2,  4,  6,  8,  6,  4,  2,  0,
413                   1,  2,  3,  4,  3,  2,  1,  0,
414                   0,  0,  0,  0,  0,  0,  0,  0 };
415 int    st_2[] = { 1, 2, 1, 0,
416                   2, 4, 2, 0,
417                   1, 2, 1, 0,
418                   0, 0, 0, 0 };
419 
420 struct S_16_c {
421               int red;
422               int green;
423               int blue;
424               };
425 struct S_16_c Solid_color[16] = {
426    {0xffff, 0xffff, 0xffff}, {0xffff, 0x0000, 0x0000},   /* white,  red     */
427    {0x0000, 0xffff, 0x0000}, {0x0000, 0x0000, 0xffff},   /* green,  blue    */
428    {0x0000, 0xffff, 0xffff}, {0xffff, 0x0000, 0xd3d3},   /* cyan,   magenta */
429    {0xffff, 0xffff, 0x0000}, {0xffff, 0x8a8a, 0xffff},   /* yellow, brown   */
430    {0x0000, 0x7000, 0x0fff}, {0x0000, 0xffff, 0x9f9f},   /* green,  green   */
431    {0x0000, 0x8a8a, 0xffff}, {0x9494, 0x0000, 0xd3d3},   /* blue,   violet  */
432    {0xffff, 0x0000, 0x9494}, {0x6969, 0x6969, 0x6969},   /* pink,   gray    */
433    {0xaeae, 0xaeae, 0xaeae}, {0x0000, 0x0000, 0x0000}    /* gray,   black   */
434   };
435 
436 int       color_x11[16] = { -1, -1, -1, -1, -1, -1, -1, -1,
437                             -1, -1, -1, -1, -1, -1, -1, -1 };
438 
439 XPoint          sm_cir[12] = { {-1,-2},{ 0,-2}, { 1,-2},  /* small circle */
440                                { 2,-1},{ 2, 0}, { 2, 1},
441                                { 1, 2},{ 0, 2}, {-1, 2},
442                                {-2, 1},{-2, 0}, {-2,-1} };
443 char            *f_name[NF_MAX];
444 char            *ProgramName = NULL;
445 char            *Xdef_Name   = "FD" ;      /* name to look for resources under */
446 char            *display, *geom, **ptr;
447 
448 int             FIRST = 1, SQUE_NR;
449 int             x00 = 0, y00 = 0;
450 int             back_to_main = 0;
451 XEvent          event, w_event, first_event;
452 
453 Display         *theDisp;
454 int             theScreen;
455 Window          rootW, theWindow, GWindow, subWindow, topWindow;
456 GC              theGC, txtGC;
457 unsigned long   fcol, bcol; // long is OK here AJJ
458 Font            mfont;
459 XFontStruct     *afinfo, *mfinfo;
460 Visual          *theVisual;
461 XImage          *theImage, *expImage, *theBelt, *expBelt;
462 int             eWIDE, eHIGH, aWIDE, eW, eH;
463 
464 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
465 
466 void RWC_setup_fims() ;
467 
468 int    FIM_opt_colors = 0 ;               /* these are for the data */
469 float  FIM_opt_thr[MAX_FIM_COLORS] ;      /* from the -fim_colors option */
470 char * FIM_opt_pos[MAX_FIM_COLORS] ,
471      * FIM_opt_neg[MAX_FIM_COLORS] ;
472 
473 int check_color() ;
474 
475 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
476 
477 unsigned short  tmp1[NCOLORS], tmp2[NCOLORS], tmp3[NCOLORS];
478 int             No_Color_init = 1, No_Grey_init = 1;
479 int             Dispcells, Planes;
480 int             repeat_status = 0, ncolors, YES_color = 0, INgrey[NCOLORS];
481 XColor          MYcol[NCOLORS], MYgrey[NCOLORS], any_col, rgb_col;
482 Colormap        CMap;
483 unsigned long   plane_masks[1], pixels[MCOLORS]; // long is OK here AJJ
484 unsigned int    nplmsk = 0, ucolors, uucolors;
485 Pixmap          pxWind;
486 
487 int             max_xlines = 0 ;
488 
489 int             spectrum = N_SPCTR; /* up to 360 degree of colors */
490 int             Im_Nr = 0, N_im = 0, I_lck = 0, tmp_Nr = 0;
491 int             N_lck = 0,  old_im = -1;
492 int             x_mag, ref_ar[IM_ARR], av_ar[IM_ARR], Cx, Cy;
493 short int       imx[IM_ARR], tmp_imx[IM_ARR] ;
494 short int       belt_ar[BELT_A], belt_arr[BELT_A];
495 int             Mltx[MAX_WIDTH], Mlty[MAX_WIDTH];
496 XPoint          a_line[NF_MAX];
497 
498 float           del1, coef1, auto_scale;
499 int             min1;
500 int             fsize, isize, ar_size;
501 int             NC;
502 int             nc_option = 0 ;
503 char            T_name[STR_L], I_name[STR_L], G_name[STR_L];
504 int             B1_action = 0, Im_frst = 0, fr_index = -7;
505 
506 int             Argc;
507 char            **Argv = NULL;
508 
509 /* these are my own ... EW */
510 
511 /* int     plot[MAT_MAX][MAT_MAX][NF_MAX],val[MAT_MAX][MAT_MAX][NF_MAX]; */
512 
513 int     * plot[MAT_MAX][MAT_MAX] , * val[MAT_MAX][MAT_MAX] ;
514 int     * LSQ_val , * LSQ_plot ;
515 
516 int     matx, maty, matx_0 = -1, maty_0 = -1;
517 int     pmin[MAT_MAX][MAT_MAX],pmax[MAT_MAX][MAT_MAX],xc,yc,mark;
518 int     xorigin[MAT_MAX][MAT_MAX],yorigin[MAT_MAX][MAT_MAX];
519 int     i,j,xpoint,ypoint,npoints,iscale,gx,gy;
520 int     xspace,yspace,grid_index, color_index;
521 char    plotbuf[10*NF_MAX],pfname[80],fnum[80];
522 int     xpoint_0 = -1, ypoint_0 = -1; /* old xpoint & ypoint */
523 float   grid_far[2*GRID_NUM], grid_coef = 1.;
524 
525 int           mytxt, idX, idY;
526 int           mdx1, mdy1;
527 char          strp[STR_L], strF[STR_L], strT[STR_L];
528 char          *color[5] = {"cyan","red","yellow","green","cornflowerblue"};
529 
530 int           im_size, offs;
531 float         gamm;
532 
533 /* Stuff for gausian smoothing of time course lines */
534 #define MAX_SMOOTH 301
535 int           AJ_nr, AJ_off, i_plot[NF_MAX];
536 float         AJ_sigma, AJ_norm;
537 float         AJ_gauss[MAX_SMOOTH];
538 float         f_plot[NF_MAX+MAX_SMOOTH];
539 
540 /* FFT stuff */
541 char      *formt[4][4] = {
542           {     "%s.%d",      "%s.%02d",      "%s.%03d",      "%s.%04d"},
543           {  "%s_%d.%d",   "%s_%d.%02d",   "%s_%d.%03d",   "%s_%d.%04d"},
544           {"%s_%02d.%d", "%s_%02d.%02d", "%s_%02d.%03d", "%s_%02d.%04d"},
545           {"%s_%03d.%d", "%s_%03d.%02d", "%s_%03d.%03d", "%s_%03d.%04d"} };
546 
547 void          csfft();
548 int           t_points, t_N_im; /* keep npoints & N_im FFT done AJJ */
549 float         t_coef1;
550 int           t_min1;
551 complex       *c_arr = NULL;    /* order: [pixel][time] AJJ */
552 complex       *r_arr = NULL;    /* for reference line */
553 int           FT_dim;           /* size of single FT */
554 int           FT_size;          /* size of all FT */
555 int           FT_disp;          /* size of displayed FT elements */
556 int           FT_done = 0;
557 int           FT_grid = 0;      /* = GRID_NUM for FFT graph */
558 int           FT_graph_on = 0;  /* FT graph is on */
559 int           grid_timed = 0;
560 struct _undo_buf {
561                  int   im;
562                  int   pix;
563                  float r;
564                  float i;
565                  float r2;
566                  float i2;
567                  };
568 struct _undo_buf *undo_buf = NULL;
569 struct _undo_buf *undo_ref = NULL; /* for reference line */
570 int           act_undo = -1, ref_undo = -1;
571 char          FT_name[100];
572 int           im_f, phase = 0;
573 #define FFT_MAG .2
574 float         fft_mag = FFT_MAG; /* fft amplitude magnify factor AJJ */
575 float         *T_ref; /* tmp pointer of LSQ_ref[0]->ts when FFT done AJJ */
576 
577 float         *avr_A = NULL;     /* array of average over several pixels */
578 int           avr_nr = 0; /* for time course average over several pixels AJ */
579 int           cancell_FT = 0;
580 /* ------ vvvvv ------ RGB mode 10.17.2001 AJ ----- vvvvv ------ */
581 XImage        *Load_Any_Arr();
582 XImage        *Load_Any_ind();
583 XImage        *Load_Any_RGB();
584 void          Load_Next_Arr();
585 void          Load_Next_ind();
586 void          Load_Next_RGB();
587 void          AJ_StoreColors();
588 int           AJ_init_RGB();
589 void          Make_RGB_lookup();
590 static int    highbit();
591 void          Syntax();
592 void          The_Help();
593 void          init_grid();
594 void          get_line_args();
595 void          init_const();
596 void          make_belt();
597 void          load_rect_str();
598 void          main_FD_EPI();
599 void          redraw_graph();
600 void          swap_2();
601 void          swap_4();
602 void          top_nr_name();
603 void          FatalError();
604 void          AJ_make_STDcol();
605 void          colmap_init();
606 void          CreateMainWindow();
607 void          New_Cursor();
608 void          MResize();
609 void          Allow_smaller_im();
610 void          HandleEvent();
611 void          DrawKey();
612 void          discard();
613 int           save_all_images();
614 void          c_swap();
615 int           save_act_im();
616 int           save_avr_array();
617 int           get_fft_mag();
618 int           read_new_im();
619 int           kill_curr_im();
620 void          Track_Cursor();
621 void          c_squeeze();
622 void          c_bright();
623 void          c_rotate();
624 void          Track_Vpointer();
625 void          InvertKey();
626 void          discard_Key();
627 void          color_init();
628 void          LetGoKey();
629 void          color_rotate();
630 void          grey_init();
631 void          grey_rotate();
632 void          color_swap();
633 void          color_squeeze();
634 void          grey_contrast();
635 void          color_bright();
636 void          grey_change();
637 void          Allow_new_name();
638 void          Cpointer_PIXWIN();
639 void          CreateGraphWindow();
640 void          Setup_subWindow();
641 void          Setup_topWindow();
642 void          Setup_keys();
643 void          Allow_smaller_gr();
644 void          Vpointer();
645 void          Cpointer();
646 void          take_file_name();
647 int           dec_indx();
648 void          draw_frame();
649 void          erase_graph();
650 
651 typedef struct { unsigned short r;
652                  unsigned short g;
653                  unsigned short b; } AJ_rgb_str;
654 int           AJ_PseudoColor = 1; /* as original pseudocolor max 12 bpp FD2 */
655                                   /* reg. colors 0-207, 208-223 std colors, */
656                                   /* 224-255 fim colors */
657 AJ_rgb_str    AJ_rgb[MCOLORS];    /* local lookup RGB array */
658 unsigned int  AJ_RGB[MCOLORS];    /* local lookup machine color packed array */
659 int           bperpix=8, border;
660 int           STD_indx[NUM_STD_COLORS + MAX_EXTRA_COLORS];
661 int           Time_avr = 1;       /* for time course or frame box average */
662 int           swap_bytes = 0;     // in place of macro #ifdef LINUX
663 
664 /****************************************************************************/
665 
666 /* ---------------- */
667    int
main(argc,argv)668    main(argc, argv)
669    int  argc;
670    char *argv[];
671 /* ---------------- */
672 {
673    int    i, j, k, m, max1;
674    char * xdef ;
675 
676    Argc = argc;
677    Argv = argv;
678    NC = 64;
679 
680    ProgramName = argv[0];  if( Xdef_Name == NULL ) Xdef_Name = ProgramName ;
681 
682    if (argc <  2)  { Syntax(); The_Help(1); }
683    display = NULL;
684    npoints = 0;
685    gamm = 1.4 ;
686    LSQ_ref[0] = NULL ;
687    init_grid();
688 
689    get_line_args(argc, argv);       /* get command line arguments and files */
690 
691 /*** ---- allocate memory for plot[][] and val[][] ---- ***/
692 
693    m = sizeof(int) * npoints ;
694 
695    LSQ_plot = (int *) malloc( m ) ;
696    LSQ_val  = (int *) malloc( m ) ;
697    if( LSQ_plot == NULL || LSQ_val == NULL ){
698       fprintf(stderr,"\n*** failure in malloc for graphs! ***\a\n");
699       exit(-1);
700    }
701 
702    for( i=0 ; i < MAT_MAX ; i++ ){
703       for( j=0 ; j < MAT_MAX ; j++ ){
704          plot[i][j] = (int *) malloc( m ) ;
705          val[i][j]  = (int *) malloc( m ) ;
706 
707          if( plot[i][j] == NULL || val[i][j] == NULL ){
708             fprintf(stderr,"\n*** failure in malloc for graphs! ***\a\n");
709             exit(-1);
710          }
711       }
712    }
713 
714 /* ---------- Open the display. --------- */
715 
716    if ( (theDisp=XOpenDisplay(display)) == NULL) {
717      fprintf(stderr, "%s: Can't open display (are X11 windows running ?). AJ\a\n"
718              ,ProgramName);
719      exit(1);
720    }
721 
722    if( !nc_option ){
723       xdef = XGetDefault(theDisp,Xdef_Name,"NColors") ;
724       if( xdef != NULL ){
725          i = strtol(xdef,NULL,0) ;
726          if( i > 4 ) NC = i ;
727       }
728    }
729 
730 /* set some image dimensions for everybody to use */
731 
732    if      ( fsize == EPS1) {
733       im_size = 64;
734       x_mag = 4;  /* 64x64 pixels format => mag = 4 */
735    }
736    else if (fsize == EPS2) {
737      im_size = 128;
738      x_mag = 2;  /* 128x128 pixels format */
739    }
740    else if (fsize == EPS3) {
741      im_size = 256;
742      x_mag = 1;  /* 256x256 pixels format */
743    }
744    else if (fsize == EPS4) {
745      im_size = 32;
746      x_mag = 8;  /* 32x32 pixels format */
747    }
748    else if (fsize == EPS5) {
749      im_size = 512;
750      x_mag = 1;  /* 512x512 pixels format */
751    }
752 //printf(" AJ fsize: %d [%d], x_mag: %d\n", fsize, EPS5, x_mag);
753    ar_size = fsize / 2 ;
754 
755    init_const();
756 
757    min1 =  32767;    /* find deviation fot central frame and set scale */
758    max1 = -32768;
759    i = ypoint*im_size + xpoint;
760    for (k=0; k < npoints; k++) {
761       if ( SAR(k)[i] < min1 ) min1 = SAR(k)[i];
762       if ( SAR(k)[i] > max1 ) max1 = SAR(k)[i];
763    }
764    del1 = max1 - min1;
765    if ( (int) del1 > 1) {
766       k = (int) (log(del1*auto_scale)/log(2.) + .5) - iscale;
767       for (i=0; i < abs(k); i++) {       /* scale graph */
768          if ( k < 0 ) scale_up();
769          else         scale_down();
770       }
771    }
772 
773    min1 =  32767;
774    max1 = -32768;
775    for (k=0; k < npoints; k++) {    /* find global min and max for main set */
776       nowim = SAR(k) ;
777       for (i=0; i < ar_size; i++) {
778          if ( nowim[i] < min1 ) min1 = nowim[i] ;
779          if ( nowim[i] > max1 ) max1 = nowim[i] ;
780       }
781    }
782    del1 = max1 - min1;
783    if (del1 < 1.) del1 = 1.;
784    coef1 = ( (float) NC - 1.) / del1;
785 
786    make_belt(belt_ar, BELT_W, im_height);     /* make reference color belt */
787    load_rect_str(belt_ar, belt_arr, BELT_W, im_height,
788                  BELT_S, 15, BELT_S, 15, 0, NC);
789 
790    main_FD_EPI();          /* Make image in the window and return Drawable */
791 
792    /** if -fim_colors was specified, check its colors for legality now **/
793 
794    if( FIM_opt_colors > 0 ){
795       for( i=0 ; i < FIM_opt_colors ; i++ ){
796          if( !check_color( FIM_opt_pos[i] ) )
797            fprintf(stderr,"\n*** color %s invalid\n",FIM_opt_pos[i]) ;
798 
799          if( !check_color( FIM_opt_neg[i] ) )
800            fprintf(stderr,"\n*** color %s invalid\n",FIM_opt_neg[i]) ;
801       }
802    }
803 
804    /* Initialize extra E.C.W. graph stuff here.  AJ */
805 
806    window_plane();  /* create graphic window with extra subwindows and keys */
807 
808    redraw_graph();                       /* draw frame and text in it */
809    DrawSubWindow();
810    DrawTopWindow();
811 
812    Put_image(0) ;                     /* put the first image */
813    XRaiseWindow(theDisp,theWindow) ;  /* bring image to top  */
814 
815 
816    x_events_loop();                              /* Main events check loop */
817 
818    exit(0);
819 
820 }       /* --- End of main() --- */
821 
822 
823 
824 /* -------- */
825    void
Syntax()826    Syntax()
827 /* -------- */
828 {
829   fprintf (stderr, "\n Functional Display (32x32, 64x64, 128x128, 256x256) in X11 window.");
830   fprintf (stderr, "\n EPI images in 256x256 Signa format are accepted too.");
831   fprintf (stderr, "\n It displays EPI time or frequency course window.");
832   fprintf (stderr, "\n\n Usage: %s [options] image1, [image2, ..., image%d]\n", ProgramName, NF_MAX);
833   fprintf (stderr, "\n Where options are:");
834   fprintf (stderr, "\n    -d display       - X11 display");
835   fprintf (stderr, "\n    -geom geometry   - initial geometry");
836   fprintf (stderr, "\n    -nc #_of_colors  - initial number of colors [2-%d] (def %d)", 200, NC);
837   fprintf (stderr, "\n    -sp #_of_degree  - range of color spectrum [0-%d] degree (def %d)", M_SP_COL, N_SPCTR);
838   fprintf (stderr, "\n    -gam gamma       - gamma correction (1 for no correction)");
839   fprintf (stderr, "\n    -num #_of_images - # of images in time course [2-%d].", NF_MAX);
840   fprintf (stderr, "\n    -im1 image_#     - first image in time course. Previous images will be ");
841   fprintf (stderr, "\n                       filled with this one for proper timing of others.");
842   fprintf (stderr, "\n    -ideal ref_file  - use ref_file for fim-like calculations" ) ;
843   fprintf (stderr, "\n    -pcthresh #      - use # as threshold for correlation" ) ;
844   fprintf (stderr, "\n    -extra           - files after this are not used in time course" );
845   fprintf (stderr, "\n                       (used instead of -num option)" );
846   fprintf (stderr, "\n    -fim_colors L thr1 pos1 neg2 ... thrL posL negL" );
847   fprintf (stderr, "\n                     - set up L thresholds and colors for FIM overlay");
848   fprintf (stderr, "\n    -gsize x y       - set graph window size to x by y pixels");
849   fprintf (stderr, "\n    -fmag val        - magnify scale of FFT by val");
850   fprintf (stderr, "\n    -grid val        - initial grid separation ");
851   fprintf (stderr, "\n    -phase           - image has negative values (for FFT)");
852   fprintf (stderr, "\n    -cf              - center image to the frame");
853   fprintf (stderr, "\n    -swap            - byte-swap data (default is no)");
854   fprintf (stderr, "\n                       *** this is a new default!");
855   fprintf (stderr, "\n");
856 }
857 
858 /* ------------ */
859    void
The_Help(ex)860    The_Help(ex)
861    int ex;
862 /* ------------ */
863 {
864   fprintf (stderr, "\n Events:\n");
865   fprintf (stderr,"\n  Program quit      : <q> or <Q>");
866   fprintf (stderr,"\n  Change to colors  : <C>");
867   fprintf (stderr,"\n  Change to B & W   : <B>");
868   fprintf (stderr,"\n  Swap colors       : <s>");
869   fprintf (stderr,"\n  Restore colors    : Button_3 at image center ");
870   fprintf (stderr,"\n  Squeeze colors    : #2 or #3 button - right side of image");
871   fprintf (stderr,"\n  Expand  colors    :                   left  side of image");
872   fprintf (stderr,"\n  Circ. color bar   : #2 or #3 button at the color bar");
873   fprintf (stderr,"\n  Color saturation  : #2 or #3 button - the top or bottom");
874   fprintf (stderr,"\n  Exact image number: press <I>, enter_number, <CR>");
875   fprintf (stderr,"\n  First image       : 1");
876   fprintf (stderr,"\n  Last image        : l");
877   fprintf (stderr,"\n  Next     image    : >");
878   fprintf (stderr,"\n  Previous image    : <");
879   fprintf (stderr,"\n                      dragging red pointer works too");
880   fprintf (stderr,"\n  Scale Plot up         : +");
881   fprintf (stderr,"\n  Scale Plot down       : -");
882   fprintf (stderr,"\n  Increase Grid Spacing : G");
883   fprintf (stderr,"\n  Decrease Grid Spacing : g");
884   fprintf (stderr,"\n  Toggle Grid and Colors: r");
885   fprintf (stderr,"\n  Toggle Frame colors   : R");
886   fprintf (stderr,"\n  Toggle time or box avr: t");
887   fprintf (stderr,"\n  Increase matrix size  : M");
888   fprintf (stderr,"\n  Decrease matrix size  : m");
889   fprintf (stderr,"\n  Increase matrix y size: V");
890   fprintf (stderr,"\n  Decrease matrix y size: v");
891   fprintf (stderr,"\n  Exact matrix size     : N #of_size <CR> (1 to %d only)", MAT_MAX);
892   fprintf (stderr,"\n  Save minigraph in ASCII file   : press <p>");
893   fprintf (stderr,"\n    [with xxx_yyy.suffix filename] press <w>");
894   fprintf (stderr,"\n  Save current image to a file   : press <S>");
895   fprintf (stderr,"\n  Save averaged image (not norm) : press <X>");
896   fprintf (stderr,"\n  Position frame in the image    : press Button_1 in the image area,");
897   fprintf (stderr,"\n                                    drag cursor, and release button.");
898   fprintf (stderr,"\n  Center frame on desired pixel  : press Button_1 over desired minigraph.");
899   fprintf (stderr,"\n  Rotate image 90 deg. clockwise : press Button_3 in [Rot] window.");
900   fprintf (stderr,"\n                counterclockwise : press Button_1 in [Rot] window.");
901   fprintf (stderr,"\n  Change to differential display : press [Diff] window. Set first and");
902   fprintf (stderr,"\n                                   last image for averaged reference.");
903   fprintf (stderr,"\n  Average of set of images       : press [AvIm] (can be used in Diff mode).");
904   fprintf (stderr,"\n  Compute FIM overlay            : press [FIM], choose ref file,threshold,");
905   fprintf (stderr,"\n                                   then press [GO]");
906   fprintf (stderr,"\n") ;
907   fprintf (stderr,"\n  Last image in time course      : L") ;
908   fprintf (stderr,"\n  Toggle autoscale of images     : A") ;
909   fprintf (stderr,"\n  Hide FIM overlay               : H") ;
910   fprintf (stderr,"\n  Hide frame in image            : h") ;
911   fprintf (stderr,"\n  Toggle overlay checkerboard    : O") ;
912   fprintf (stderr,"\n  Read image into program        : F (for file)") ;
913   fprintf (stderr,"\n  Remove image from program      : K (for kill)") ;
914   fprintf (stderr,"\n  Move to image 1..9             : 1,2,...9") ;
915   fprintf (stderr,"\n  Toggle common graph baselines  : b") ;
916   fprintf (stderr,"\n  Toggle baseline to zero        : x") ;
917   fprintf (stderr,"\n");
918   fprintf (stderr,"\n  Add/[subtract] 3600 from pixel : D / [d]");
919   fprintf (stderr,"\n  In FT edit mode: ");
920   fprintf (stderr,"\n                increase value   : Arrow Up");
921   fprintf (stderr,"\n                decrease value   : Arrow Down");
922   fprintf (stderr,"\n          Shift or Control Arrow : larger changes ");
923   fprintf (stderr,"\n                undo last change : u");
924   fprintf (stderr,"\n                undo all changes : U");
925 
926 #ifdef USE_MCW
927   fprintf (stderr,"\n  Show MCW logo              : 0") ;
928 #endif
929   fprintf (stderr,"\n\n ");
930 
931   if (ex == 1) exit(0);                 /* 1 -> 0   18 Sep 2018 [rickr] */
932 }
933 
934 /* ------------------------- */
935    void
get_line_args(argc,argv)936    get_line_args(argc, argv)
937    int  argc;
938    char *argv[];
939 /* ------------------------- */
940 {
941    register int i, j, k, nopt, nnn;
942    int          sp;
943    float        fff;
944 
945    MRI_IMAGE * imtemp ;
946    int input_conversion = 0 ;
947    int nextra = -1 ;
948 
949    nopt = 0;
950    for (i = 1; i < argc; i++) { /* ------- Options ------- */
951 
952       if (!strncmp(argv[i], "-d", 2)) {          /* display */
953          if (++i >= argc) { Syntax (); exit(1); }
954          display = argv[i];
955          nopt++; nopt++;
956          continue;
957       }
958       if (!strncmp(argv[i], "-geo", 4)) {          /* initial geometry */
959          if (++i >= argc) { Syntax (); exit(1); }
960          geom  = argv[i];
961          nopt++; nopt++;
962          continue;
963       }
964       if (!strncmp(argv[i], "-h", 2)) {          /* help */
965          Syntax();
966          The_Help(1);
967       }
968       if (!strncmp(argv[i], "-nc", 3)) {         /* # of colors */
969          if (++i >= argc) { Syntax (); exit(1); }
970          nnn = atoi(argv [i]);
971          if (nnn < 2 || nnn > NCOLORS ) { Syntax(); exit(1); }
972          NC = nnn;  nc_option = 1 ;
973          nopt++; nopt++;
974          continue;
975       }
976       if (strncmp(argv [i], "-sp", 3) == 0) {
977          if (++i >= argc) { Syntax(); exit(1); }
978          ptr = argv;
979          sp = strtod(argv[i], ptr);
980          if ( **ptr || (sp < 1) || (sp > M_SP_COL) ) {
981             fprintf (stderr, "\n !!! Wrong degree value: -sp %d !!!\a\n",sp);
982             fprintf (stderr, "\n !!! For help type: %s -h \a\n\n", ProgramName);
983             exit(3);
984          }
985          spectrum = sp;
986          nopt++; nopt++;
987          continue;
988       }
989       if (strncmp(argv [i], "-fmag", 5) == 0) {
990          if (++i >= argc) Syntax ();
991          ptr = argv;
992          fff = strtod(argv[i], ptr);
993          if ( **ptr || (fff <= 0.) ) {
994             fprintf (stderr, "\n !!! Wrong fft magnify value: %g !!!\n\n",fff);
995             Syntax();
996          }
997          fft_mag = fff * FFT_MAG;
998          nopt++; nopt++;
999          continue;
1000       }
1001       if (strncmp(argv [i], "-gam", 4) == 0) {
1002          if (++i >= argc) Syntax ();
1003          ptr = argv;
1004          fff = strtod(argv[i], ptr);
1005          if ( **ptr || (fff <= 0.) ) {
1006             fprintf (stderr, "\n !!! Wrong gamma value: %g !!!\a\n\n",fff);
1007             exit(3) ;
1008          }
1009          gamm = fff;
1010          nopt++; nopt++;
1011          continue;
1012       }
1013       if (strncmp(argv [i], "-num", 4) == 0) {
1014          if (++i >= argc) { Syntax(); exit(1); }
1015          ptr = argv;
1016          npoints = strtod(argv[i], ptr) + .5;
1017          if ( **ptr || (npoints < 1)) {
1018             fprintf (stderr, "\n !!! Too few images specified !!!\a\n\n");
1019             exit(1); /* now symbolic for min npoints = 1 . AJ */
1020          }
1021          nopt++; nopt++;
1022          continue;
1023       }
1024       if (strncmp(argv [i], "-pha", 4) == 0) {
1025 	 phase = 1;
1026          nopt++;
1027          continue;
1028       }
1029       if (strncmp(argv [i], "-cf", 3) == 0) {
1030 	 c_f = 1;
1031          nopt++;
1032          continue;
1033       }
1034       if (strncmp(argv [i], "-grid", 4) == 0) {
1035          if (++i >= argc) { Syntax(); exit(1); }
1036          ptr = argv;
1037          fff = strtod(argv[i], ptr);
1038          if ( **ptr || (fff < .1)) {
1039             fprintf (stderr,
1040             "\n !!! grid spacing too small [< .1]: %g !!!\a\n\n", fff);
1041             exit(1);
1042          }
1043          if ( fff < 2 ) grid_coef = GRID_COEF;
1044          else           grid_coef = 1.;
1045          grid_index = 0;
1046          grid_far[0] = fff;
1047          grid_far[1] = 2.*fff;
1048          grid_far[2] = 5.*fff;
1049          grid_timed = 1;
1050          nopt++; nopt++;
1051          continue;
1052       }
1053       if (strncmp(argv [i], "-im1", 4) == 0) {
1054          if (++i >= argc) { Syntax(); exit(1); }
1055          ptr = argv;
1056          Im_frst = strtod(argv[i], ptr) + .5;
1057          if ( **ptr || (Im_frst < 1)) {
1058             fprintf (stderr, "\n !!! First_image_# < 1 in -im1 !!!\a\n\n");
1059             exit(1);
1060          }
1061          nopt++; nopt++;
1062          continue;
1063       }
1064       if (strncmp(argv [i], "-mag", 4) == 0) {
1065          fprintf (stderr, "\n !!! No more -mag option in use !!!");
1066          fprintf (stderr, "\n !!! Resize window using mouse  !!!\a\n\n");
1067          if (++i >= argc) { Syntax(); exit(1); }
1068          nopt++; nopt++;
1069          continue;
1070       }
1071       /* allow the user to specify swapping bytes */
1072       if (strncmp(argv [i], "-swap", 4) == 0) {
1073          swap_bytes = 1;
1074          nopt++;
1075          continue;
1076       }
1077 
1078 /***************************************************************************/
1079 
1080      if( strncmp(argv[i],"-pcthresh",4) == 0 ){
1081         if( ++i >= argc ) { Syntax(); exit(1); }
1082         RWC_pcthresh = strtod( argv[i] , NULL ) ;
1083         if( RWC_pcthresh <= 0.0 || RWC_pcthresh >= 1.0 ){
1084            fprintf(stderr,"-pcthresh %11.4g is illegal!\a\n",RWC_pcthresh) ;
1085            exit(1);
1086         }
1087         nopt++ ; nopt++ ;
1088         continue ;
1089      }
1090 
1091      if( strncmp(argv[i],"-ideal",4) == 0 ){
1092         if( RWC_ideal != NULL ){
1093            fprintf(stderr,"cannot have 2 -ideal options!\a\n") ;
1094            exit(1) ;
1095         }
1096         if( ++i >= argc ) { exit(1); }
1097 
1098         RWC_ideal = RWC_read_time_series( argv[i] ) ;
1099 
1100         if( RWC_ideal == NULL ){
1101            fprintf(stderr,"cannot read -ideal %s\a\n",argv[i]) ;
1102            exit(1);
1103         }
1104         RWC_do_overfim = 1 ;
1105         nopt++ ; nopt++ ;
1106         continue ;
1107      }
1108 
1109      if( strncmp(argv[i],"-extra",3) == 0 ){
1110         if( nextra > 0 ){
1111            fprintf(stderr,"cannot have 2 -extra options!\a\n") ;
1112            exit(1) ;
1113         }
1114         nextra = i ;  /* do NOT count this in nopt! */
1115         continue ;
1116      }
1117 
1118      if( strncmp(argv[i],"-gsize",4) == 0 ){
1119         if( i+2 >= argc ){
1120            fprintf(stderr,"\n*** nothing follows -gsize!\a\n");
1121            exit(1) ;
1122         }
1123         gx_max = strtod( argv[++i] , NULL ) ;
1124         gy_max = strtod( argv[++i] , NULL ) ;
1125         if( gx_max <  100 || gy_max <  100 ||
1126 	    gx_max > 1024 || gy_max > 1024   ){
1127            fprintf(stderr,"\n*** illegal values following -gsize!\n");
1128            exit(1) ;
1129         }
1130         nopt += 3 ;
1131         continue ;
1132      }
1133 
1134      if( strncmp(argv[i],"-fim_colors",8) == 0 ){
1135         int   ival , ii , good ;
1136         float fval ;
1137 
1138         if( FIM_opt_colors > 0 ){
1139            fprintf(stderr,"\n*** cannot have 2 -fim_colors options!\a\n") ;
1140            exit(1) ;
1141         }
1142         if( ++i >= argc ){
1143            fprintf(stderr,"\n*** nothing follows -fim_colors!\a\n") ;
1144            exit(1) ;
1145         }
1146 
1147         ival = strtol( argv[i] , NULL , 10 ) ;
1148         if( ival <= 0 || ival > MAX_FIM_COLORS ){
1149            fprintf(stderr,"\n*** illegal value for -fim_colors: %d\a\n",ival) ;
1150            exit(1) ;
1151         }
1152         FIM_opt_colors = ival ;
1153         if( i + 3*FIM_opt_colors >= argc ){
1154            fprintf(stderr,"\n*** not enough values follow -fim_colors!\a\n");
1155            exit(1) ;
1156         }
1157 
1158         good = 1 ;
1159         for( ii=0 ; ii < FIM_opt_colors ; ii++ ){
1160            fval = strtod( argv[++i] , NULL ) ;
1161            if( fval <= 0.0 || fval >= 1.0 ){
1162               fprintf(stderr,"\n*** illegal fim_colors threshold %s\a\n",argv[i]);
1163               good = 0 ;
1164            }
1165            FIM_opt_thr[ii] = fval ;      /* store threshold and color strings */
1166            FIM_opt_pos[ii] = argv[++i] ;
1167            FIM_opt_neg[ii] = argv[++i] ;
1168         }
1169         if( !good ){
1170            fprintf(stderr,"\n*** cannot continue from fim_colors errors!\n");
1171            exit(1) ;
1172         }
1173         nopt += 3 * FIM_opt_colors + 2 ;
1174         continue ;
1175      }
1176 
1177 /***************************************************************************/
1178 
1179    }
1180    nopt++;                                   /* Files to read (minimum one) */
1181 
1182    if( nextra > 0 && nextra <= nopt ){
1183       fprintf(stderr,"\n*** -extra option too early!\a\n"); exit(1) ;
1184    }
1185 
1186    if( nextra > nopt && npoints > 0 ){
1187       fprintf(stderr,"\n*** -extra option conflicts with -num option!\a\n");
1188       exit(1) ;
1189    }
1190 
1191    if ( nopt > (argc-1) || nopt < (argc - NF_MAX) ) {  /* Nr of files check */
1192       fprintf (stderr, "\n Wrong # of files. %d files entered :\a\n", argc-nopt);
1193       for(i=nopt, j=1; i < argc; i++, j++)
1194          fprintf (stderr, "  %3d -  %s\n", j, argv[i]);
1195       exit(1);
1196    }
1197 
1198    N_im = argc-nopt;                                /* # of images */
1199 
1200    if( nextra > nopt ){
1201       N_im -- ;                                     /* -1 for -extra option */
1202       npoints = nextra - nopt ;                     /* no. points in series */
1203    } else if( npoints == 0 || npoints > N_im ){
1204       npoints = N_im ;
1205    }
1206 
1207    if( N_im < 1 || N_im > NF_MAX ){
1208       fprintf (stderr, "\n Wrong # of files. %d files entered :\a\n", argc-nopt);
1209       exit(1) ;
1210    }
1211 
1212    if ( Im_frst > N_im ) {
1213       fprintf (stderr, "\n!!! First_im_# in -im1 is bigger than number of images!!!\a\n");
1214       exit(1);
1215    }
1216 
1217    for( i=0,k=0 ; i < N_im ; i++,k++){
1218       if( strncmp(Argv[k+nopt],"-extra",3) == 0 ) k++ ;  /* skip -extra */
1219       f_name[i] = Argv[k+nopt] ;
1220    }
1221    if( N_im == 1 ){
1222       N_im = npoints = 2 ;
1223       f_name[1] = malloc( strlen(f_name[0]) + 1 ) ;
1224       strcpy( f_name[1] , f_name[0] ) ;
1225    }
1226 
1227    for (i=0; i < Im_frst-1; i++) f_name[i] = f_name[Im_frst-1];
1228 
1229    dim_allim = N_im + INC_ALLIM ;  /* allow for some extra images */
1230 
1231    allim = (MRI_IMAGE **) malloc( sizeof(MRI_IMAGE *) * dim_allim ) ;
1232    if( allim == NULL ){
1233       fprintf(stderr,"\n*** cannot malloc allim\a\n") ;
1234       MRI_FATAL_ERROR ;
1235    }
1236 
1237    /* read and check the length of the first file for validity */
1238 
1239    imtemp = mri_read_nsize( f_name[0] ) ;
1240 
1241    /* swap based on command-line now                   27 Aug 2004 [rickr] */
1242 
1243    if ( swap_bytes && imtemp->kind == MRI_short ) {
1244      swap_2(MRI_SHORT_PTR(imtemp), imtemp->nx*imtemp->ny*2);
1245    }
1246    else if ( swap_bytes && imtemp->kind == MRI_float ) {
1247      swap_4(MRI_FLOAT_PTR(imtemp), imtemp->nx*imtemp->ny*4);
1248    }
1249 
1250    if( imtemp == NULL ) exit(-1) ;
1251    if( imtemp->kind == MRI_short ){
1252       allim[0] = imtemp ;
1253    } else {
1254       allim[0] = mri_to_short( 0.0 , imtemp ) ;
1255       mri_free( imtemp ) ;
1256       mri_add_name( f_name[0] , allim[0] ) ;
1257       input_conversion++ ;
1258    }
1259 
1260    isize = 2 * allim[0]->nx * allim[0]->ny ;
1261    if ( (isize != EPS1) && (isize != EPS2)
1262      && (isize != EPS3) && (isize != EPS4) && (isize != EPS5) ) {
1263       fprintf (stderr, "\n\n !!! File %s has illegal dimensions !!!\a\n", f_name[0]);
1264       exit(-1);
1265    }
1266 
1267    if ( allim[0]->ny > 256 ) im_height = 512; // new for 512 image size
1268    im_tmp_ar = mri_new( im_height , im_height , MRI_short ) ; // max size
1269    tmp_ar    = mri_data_pointer( im_tmp_ar ) ;
1270 
1271    fsize   = isize;
1272    ar_size = fsize / 2 ;
1273 
1274    printf("\nReading files ") ; fflush(stdout) ;
1275 
1276    for( i=1 ; i < N_im ; i++ ){
1277 
1278       if( i%10 == 9 ){ printf(".") ; fflush(stdout) ; }
1279 
1280       imtemp = mri_read_nsize( f_name[i] ) ;
1281 
1282       /* we already know whether to swap     26 Aug 2004 [rickr] */
1283       if ( swap_bytes && imtemp->kind == MRI_short ) {
1284         swap_2(MRI_SHORT_PTR(imtemp), imtemp->nx*imtemp->ny*2);
1285       }
1286       else if ( swap_bytes && imtemp->kind == MRI_float ) {
1287         swap_4(MRI_FLOAT_PTR(imtemp), imtemp->nx*imtemp->ny*4);
1288       }
1289 
1290       if( imtemp == NULL ){
1291          fprintf(stderr,"\n*** %s does not have exactly one image!\a\n",
1292                  f_name[i]) ;
1293          exit(1) ;
1294       }
1295 
1296       if( imtemp->kind == MRI_short ){
1297          allim[i] = imtemp ;
1298       } else {
1299          allim[i] = mri_to_short( 0.0 , imtemp ) ;
1300          mri_free( imtemp ) ;
1301          mri_add_name( f_name[i] , allim[i] ) ;
1302          input_conversion++ ;
1303       }
1304       isize = 2 * allim[i]->nx * allim[i]->ny ;
1305       if ( i < npoints && isize != fsize) {  /* check lengths of other files */
1306          fprintf (stderr, "\n\n !!! File %s has different dimensions !!!\a\n",
1307                   f_name[i]);
1308          exit(1);
1309       } else if( isize != EPS1 && isize != EPS2
1310               && isize != EPS3 && isize != EPS4 && isize != EPS5 ){
1311          fprintf(stderr,"\n*** file %s has illegal dimensions!\a\n",f_name[i]);
1312          exit(1) ;
1313       }
1314    }
1315    printf("\n"); fflush(stdout) ;
1316    if( input_conversion ){
1317       fprintf(stderr,
1318               "\n*** %d files converted to shorts on input!\n",
1319               input_conversion ) ;
1320    }
1321 
1322    if( RWC_ideal != NULL ){
1323       FIM_edit_time_series( RWC_ideal ) ;
1324       if( RWC_ideal->len < npoints ){
1325          fprintf(stderr,"*** -ideal %s too short!\n",RWC_ideal->fname) ;
1326          RWC_free_time_series( RWC_ideal ) ;
1327          RWC_ideal = NULL ;
1328          RWC_do_overfim = 0 ;
1329          if( RWC_imover != NULL ) { free(RWC_imover) ; RWC_imover = NULL ; }
1330       } else {
1331          kFI3_refsum_count = -1 ;
1332       }
1333    }
1334 
1335 }
1336 
1337 /* ------------------------------------------- Main link from main() C */
1338    void
main_FD_EPI()1339    main_FD_EPI()
1340 /* ------------------------------------------------------------------- */
1341 {
1342    int        i;
1343    XGCValues  gcv;
1344 
1345    ucolors = SQUE_NR = ncolors = NC;
1346    uucolors = NC - 1;
1347    expImage = NULL;
1348 
1349    for (i=0; i<im_height; i++) {   /* init MResize() lookup tables */
1350       Mltx[i] = i;
1351       Mlty[i] = i;
1352    }
1353 
1354    top_nr_name(allim[0]->name);
1355 
1356 /* ---------- Open the display. --------- */
1357 
1358    theScreen = DefaultScreen(theDisp);          /* Set Graphic variables */
1359    rootW     = RootWindow(theDisp,theScreen);
1360    theGC     = DefaultGC(theDisp,theScreen);
1361    theVisual = DefaultVisual(theDisp,theScreen);
1362    CMap      = DefaultColormap(theDisp, theScreen);
1363    Planes    = DisplayPlanes(theDisp, theScreen);
1364 
1365 #if defined(__cplusplus) || defined(c_plusplus)
1366 
1367    if ( (theVisual->c_class != PseudoColor) &&
1368         (theVisual->c_class != TrueColor) &&
1369         (theVisual->c_class != DirectColor) )
1370       FatalError("This program requires PseudoColor or TrueColor or DirectColor modes only. AJ");
1371 
1372    if ( theVisual->c_class != PseudoColor ) AJ_PseudoColor = 0;
1373 #else
1374 
1375    if ( (theVisual->class != PseudoColor) &&
1376         (theVisual->class != TrueColor) &&
1377         (theVisual->class != DirectColor) )
1378       FatalError("This program requires PseudoColor or TrueColor or DirectColor modes only. AJ");
1379 
1380    if ( theVisual->class != PseudoColor ) AJ_PseudoColor = 0;
1381 #endif
1382 
1383    if (!(XAllocNamedColor(theDisp, CMap, "black", &any_col, &rgb_col)))
1384       FatalError ("XAllocNamedColor problem. AJ");
1385    fcol = any_col.pixel;
1386 
1387    if (!(XAllocNamedColor(theDisp, CMap, "grey35", &any_col, &rgb_col)))
1388       FatalError ("XAllocNamedColor problem. AJ");
1389    bcol = any_col.pixel;
1390 
1391    if ( AJ_PseudoColor ) {
1392       if (!(XAllocColorCells(theDisp, CMap, True, plane_masks, nplmsk,
1393          pixels, ucolors))) FatalError ("XAllocColorCells problem. AJ");
1394    }
1395    else {
1396       if ( (AJ_init_RGB()) )
1397          FatalError ("AJ_init_RGB problem. AJ");;
1398       AJ_make_STDcol(Solid_color, NUM_STD_COLORS);
1399    }
1400 
1401    colmap_init();                              /* Initialize color map */
1402 
1403 
1404 #ifdef USE_MCW
1405    mcw_load() ;
1406    for( i=0 ; i < IM_ARR ; i++ ) tmp_ar[i] = mcw_im[i] ;
1407    SIZE_tmp_ar( im_height ) ;
1408 #else
1409          /* Create theImage from ar[] #1. Do NOT use here Put_image() ! AJ */
1410    nowim = SAR(0) ;
1411    for (i=0; i < ar_size; i++)                   /* renormalize data */
1412       tmp_ar[i] = (int)((float)(nowim[i]-min1)*coef1 + .5);
1413    SIZE_tmp_ar( allim[0]->nx ) ;
1414 #endif
1415 
1416    Resample(im_tmp_ar);
1417 
1418    theImage = Load_Any_Arr(imx,im_height,im_height);
1419 
1420    theBelt  = Load_Any_Arr(belt_arr,BELT_W,im_height);
1421 
1422    eWIDE = theImage->width;  eHIGH = theImage->height;
1423    eW = theBelt->width;      eH = theBelt->height;
1424    aWIDE = eWIDE + eW;
1425 
1426    if (!(afinfo = XLoadQueryFont(theDisp, KFONT)))
1427       if (!(afinfo = XLoadQueryFont(theDisp, "fixed"))) {
1428          sprintf(strp, "Can't open %s or fixed fonts\n", KFONT);
1429          FatalError (strp);
1430       }
1431 
1432    mfont=afinfo->fid;
1433    XSetFont(theDisp,theGC,mfont);
1434    XSetForeground(theDisp,theGC,fcol);
1435    XSetBackground(theDisp,theGC,bcol);
1436 
1437    CreateMainWindow(geom, Argc, Argv);   /* Set theWindow properties */
1438 
1439    gcv.function = GXcopy;                /* Extra, Small Text Graphic Context */
1440    gcv.foreground = fcol;
1441    txtGC = XCreateGC(theDisp, theWindow, GCForeground|GCFunction, &gcv);
1442 
1443    /** load text font from one of the candidate list **/
1444 
1445    tfont = XGetDefault(theDisp, Xdef_Name , "TextFont");
1446    if( tfont != NULL ) tfont_hopefuls[0] = tfont ;
1447    else                tfont_hopefuls[0] = TFONT ;
1448    { int ifont ;
1449      for( ifont=0 ; tfont_hopefuls[ifont] != NULL ; ifont++ ){
1450         mfinfo = XLoadQueryFont(theDisp, tfont_hopefuls[ifont]) ;
1451         if( mfinfo != NULL ) break ;
1452      }
1453      if( mfinfo == NULL ){
1454          FatalError("Can't open any text font!\n") ;
1455      }
1456      tfont = tfont_hopefuls[ifont] ;
1457    }
1458    mfont=mfinfo->fid;
1459    XSetFont(theDisp,txtGC,mfont);
1460    XSetForeground(theDisp,txtGC,fcol);
1461    XSetBackground(theDisp,txtGC,bcol);
1462 
1463    New_Cursor(theDisp, theWindow, XC_left_ptr, "red", "white"); /* cursor */
1464 
1465                                                   /* Adjust size before Show */
1466    MResize(&expImage,&eWIDE,&eHIGH,theImage,eWIDE,eHIGH);
1467    MResize(&expBelt,&eW,&eH,theBelt,eW,eH);
1468 
1469    XSelectInput(theDisp, theWindow, ExposureMask | KeyPressMask
1470            | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask);
1471 
1472    XMapWindow(theDisp,theWindow);               /* Show theImage first time */
1473 
1474    while (1) {
1475       XNextEvent(theDisp, &first_event);        /* Wait for window on */
1476       switch (first_event.type) {
1477          case Expose: {
1478            XExposeEvent *e = (XExposeEvent *) &first_event;
1479            if (e->window == theWindow) {
1480             XPutImage(theDisp, theWindow, theGC, expImage,
1481                       e->x, e->y, e->x, e->y, e->width, e->height);
1482             XPutImage(theDisp, theWindow, theGC, expBelt,
1483                       0, 0, eHIGH, 0, eW, eH);
1484              Allow_smaller_im(Argc, Argv);
1485          }
1486 #ifdef USE_MCW
1487    sleep(1) ;    /* show the logo for a second! */
1488 #endif
1489          return;
1490        }
1491 
1492          case KeyPress:
1493          case ButtonPress:
1494          case ButtonRelease:
1495          case ConfigureNotify:
1496          case CirculateNotify:
1497          case MapNotify:
1498          case DestroyNotify:
1499          case GravityNotify:
1500          case ReparentNotify:
1501          case UnmapNotify:
1502          break;
1503 
1504          default:                /* ignore unexpected events */
1505          break;
1506       }
1507    }
1508 }        /* end of main_FD_EPI() */
1509 
1510 /* ----------------------- */
x_events_loop()1511    void x_events_loop()
1512 /* ----------------------- */
1513 {
1514    register int i;
1515 
1516    for (i=LAST_K; i<N_KEYS; i++) XUnmapWindow(theDisp,  key[i].wid);
1517    back_to_main = 0;
1518    while (1) {
1519      if (repeat_status) {       /* For repeated action when button pressed */
1520        if (XCheckWindowEvent(theDisp, theWindow, ButtonReleaseMask, &w_event))
1521          event = w_event;
1522      }
1523      else {
1524        XNextEvent(theDisp, &event);  /* single event loop */
1525      }
1526      HandleEvent(&event);
1527      if(back_to_main) return;
1528    }
1529 }
1530 
1531 int C_count = -1;
1532 /* ------------------ */
1533    void
HandleEvent(event)1534    HandleEvent(event)
1535    XEvent *event;
1536 /* ------------------ */
1537 {
1538    Window wind;
1539 
1540  switch (event->type) {
1541 
1542    case Expose: {
1543       XExposeEvent *e = (XExposeEvent *) event;
1544       wind = e->window;
1545       if (wind == theWindow) {
1546          XPutImage(theDisp, theWindow, theGC, expImage,
1547                    e->x, e->y, e->x, e->y, e->width, e->height);
1548          XPutImage(theDisp, theWindow, theGC, expBelt,
1549                    0, 0, eHIGH, 0, eW, eH);
1550       }
1551       else if (wind == subWindow) {
1552          DrawSubWindow();
1553       }
1554       else if (wind == topWindow) {
1555          DrawTopWindow();
1556       }
1557       else {
1558          int  i;
1559          for (i=0; i < N_KEYS; i++)
1560             if (key[i].wid==wind) DrawKey(i);
1561          }
1562       }
1563        break;
1564 
1565    case KeyPress: {
1566       XKeyEvent *key_event = (XKeyEvent *) event;
1567       char      buf[128];
1568       int       i;
1569       KeySym    ks;
1570       XComposeStatus status;
1571 
1572       buf[0] = 0;
1573       XLookupString(key_event, buf, 128, &ks, &status);
1574       if (buf[0]=='q' || buf[0]=='Q'){
1575 #ifdef USE_MCW
1576          XRaiseWindow(theDisp,theWindow) ;
1577          Put_image(-1) ;
1578          sleep(1) ;
1579 #endif
1580          XFreePixmap( theDisp , pxWind ) ;
1581          XCloseDisplay( theDisp ) ;
1582 	 exit(0);
1583       }
1584       if ( (I_lck == 0) && (buf[0]=='I') ) {    /* init image number */
1585          I_lck = 1;
1586          New_Cursor(theDisp, theWindow, XC_hand2, "red", "white");
1587          New_Cursor(theDisp,   GWindow, XC_hand2, "yellow", "red");
1588          break;
1589       }
1590       if ( (N_lck == 0) && (buf[0]=='N') ) {  /* init grid resol. number */
1591          N_lck = 1;
1592          matx_0 = matx;
1593          maty_0 = maty;
1594          New_Cursor(theDisp, theWindow, XC_hand2, "red", "white");
1595          New_Cursor(theDisp,   GWindow, XC_hand2, "yellow", "red");
1596          break;
1597       }
1598 
1599       /* Arrows keys for edit YYY */
1600       if ( FT1_pressed ) {
1601          if ( ks == XK_Right ) {
1602             int i_tmp = Im_Nr;
1603 
1604             if ( Im_Nr < (npoints - 1) ) Im_Nr += 1;
1605             if ( i_tmp != Im_Nr ) {
1606                XClearWindow(theDisp, GWindow);
1607                Put_image(Im_Nr);
1608                DrawSubWindow();
1609                DrawTopWindow();
1610                discard(KeyPressMask, event);
1611             }
1612             break;
1613          }
1614          else if ( ks == XK_Left ) {
1615             int min_im = 0, i_tmp = Im_Nr;
1616 
1617             if(Im_Nr > min_im) Im_Nr -= 1;
1618             if ( i_tmp != Im_Nr ) {
1619                XClearWindow(theDisp, GWindow);
1620                Put_image(Im_Nr);
1621                DrawSubWindow();
1622                DrawTopWindow();
1623                discard(KeyPressMask, event);
1624             }
1625             break;
1626          }
1627          else if ( ks == XK_Up ) {
1628             int   i, j, nn;
1629             float f0 = fft_mag, f1, f2, f3, fff = 1.1;
1630 
1631             if ( key_event->state & ShiftMask )   fff = 1.5;
1632             if ( key_event->state & ControlMask ) fff = 2.3;
1633             nn = act_undo + 1;
1634             act_undo += ar_size;
1635             undo_buf = realloc(undo_buf, (act_undo+1)*sizeof(struct _undo_buf));
1636             if ( undo_buf != NULL ) {
1637                for ( i=0, j=nn; i < ar_size; j++, i++) {
1638                   undo_buf[j].im  = Im_Nr;
1639                   undo_buf[j].pix = i;
1640                   undo_buf[j].r   = c_arr[i*FT_dim+Im_Nr+1].r;
1641                   undo_buf[j].i   = c_arr[i*FT_dim+Im_Nr+1].i;
1642                   undo_buf[j].r2  = c_arr[(i+1)*FT_dim-Im_Nr-1].r;
1643                   undo_buf[j].i2  = c_arr[(i+1)*FT_dim-Im_Nr-1].i;
1644                   f1 = c_arr[i*FT_dim+Im_Nr+1].r *= fff;
1645                   f2 = c_arr[i*FT_dim+Im_Nr+1].i *= fff;
1646                   c_arr[(i+1)*FT_dim-Im_Nr-1].r  *= fff;
1647                   c_arr[(i+1)*FT_dim-Im_Nr-1].i  *= fff;
1648 
1649                   f3 = f0 * sqrt(f1*f1 + f2*f2);
1650                   if ( f3 > 32767. ) f3 = 32767.;
1651                   SAR(Im_Nr)[i] = f3;
1652                }
1653                redraw_graph() ;
1654                DrawSubWindow();
1655             }
1656             else {
1657                act_undo = -1;
1658                fprintf(stderr,"\n*** cannot realloc undo_buf\a\n") ;
1659                XBell(theDisp, 100);
1660             }
1661 
1662             if ( RWC_ideal != NULL  && RWC_ideal->len >= npoints ) {
1663                ref_undo += 1;
1664                undo_ref =
1665                     realloc(undo_ref, (ref_undo+1)*sizeof(struct _undo_buf));
1666                if ( undo_ref != NULL ) {
1667                   j = ref_undo;
1668                   undo_ref[j].im  = Im_Nr;
1669                   undo_ref[j].r   = r_arr[Im_Nr+1].r;
1670                   undo_ref[j].i   = r_arr[Im_Nr+1].i;
1671                   undo_ref[j].r2  = r_arr[FT_dim-Im_Nr-1].r;
1672                   undo_ref[j].i2  = r_arr[FT_dim-Im_Nr-1].i;
1673                   f1 = r_arr[Im_Nr+1].r   *= fff;
1674                   f2 = r_arr[Im_Nr+1].i   *= fff;
1675                   r_arr[FT_dim-Im_Nr-1].r *= fff;
1676                   r_arr[FT_dim-Im_Nr-1].i *= fff;
1677                   f3 = f0 * sqrt(f1*f1 + f2*f2);
1678                   if ( f3 > 32767. ) f3 = 32767.;
1679                   RWC_ideal->ts[Im_Nr] = f3;
1680                   redraw_graph() ;
1681                   DrawSubWindow();
1682                }
1683             }
1684             else {
1685                ref_undo = -1;
1686                fprintf(stderr,"\n*** cannot realloc undo_ref\a\n") ;
1687                XBell(theDisp, 100);
1688             }
1689             discard(KeyPressMask, event);
1690             break;
1691          }
1692          else if ( ks == XK_Down ) {
1693             int   i, j, nn;
1694             float f0 = fft_mag, f1, f2, f3, fff = 1./1.1;
1695 
1696             if ( key_event->state & ShiftMask )   fff = 1./1.5;
1697             if ( key_event->state & ControlMask ) fff = 1./2.3;
1698             nn = act_undo + 1;
1699             act_undo += ar_size;
1700             undo_buf = realloc(undo_buf, (act_undo+1)*sizeof(struct _undo_buf));
1701             if ( undo_buf != NULL ) {
1702                for ( i=0, j=nn; i < ar_size; j++, i++) {
1703                   undo_buf[j].im  = Im_Nr;
1704                   undo_buf[j].pix = i;
1705                   undo_buf[j].r   = c_arr[i*FT_dim+Im_Nr+1].r;
1706                   undo_buf[j].i   = c_arr[i*FT_dim+Im_Nr+1].i;
1707                   undo_buf[j].r2  = c_arr[(i+1)*FT_dim-Im_Nr-1].r;
1708                   undo_buf[j].i2  = c_arr[(i+1)*FT_dim-Im_Nr-1].i;
1709                   f1 = c_arr[i*FT_dim+Im_Nr+1].r *= fff;
1710                   f2 = c_arr[i*FT_dim+Im_Nr+1].i *= fff;
1711                   c_arr[(i+1)*FT_dim-Im_Nr-1].r  *= fff;
1712                   c_arr[(i+1)*FT_dim-Im_Nr-1].i  *= fff;
1713 
1714                   f3 = f0 * sqrt(f1*f1 + f2*f2);
1715                   if ( f3 > 32767. ) f3 = 32767.;
1716                   SAR(Im_Nr)[i] = f3;
1717                }
1718                redraw_graph() ;
1719                DrawSubWindow();
1720             }
1721             else {
1722                act_undo = -1;
1723                fprintf(stderr,"\n*** cannot realloc undo_buf\a\n") ;
1724                XBell(theDisp, 100);
1725             }
1726 
1727             if ( RWC_ideal != NULL  && RWC_ideal->len >= npoints ) {
1728                ref_undo += 1;
1729                undo_ref =
1730                   realloc(undo_ref, (ref_undo+1)*sizeof(struct _undo_buf));
1731                if ( undo_ref != NULL ) {
1732                   j = ref_undo;
1733                   undo_ref[j].im  = Im_Nr;
1734                   undo_ref[j].r   = r_arr[Im_Nr+1].r;
1735                   undo_ref[j].i   = r_arr[Im_Nr+1].i;
1736                   undo_ref[j].r2  = r_arr[FT_dim-Im_Nr-1].r;
1737                   undo_ref[j].i2  = r_arr[FT_dim-Im_Nr-1].i;
1738                   f1 = r_arr[Im_Nr+1].r   *= fff;
1739                   f2 = r_arr[Im_Nr+1].i   *= fff;
1740                   r_arr[FT_dim-Im_Nr-1].r *= fff;
1741                   r_arr[FT_dim-Im_Nr-1].i *= fff;
1742                   f3 = f0 * sqrt(f1*f1 + f2*f2);
1743                   if ( f3 > 32767. ) f3 = 32767.;
1744                   RWC_ideal->ts[Im_Nr] = f3;
1745                   redraw_graph() ;
1746                   DrawSubWindow();
1747                }
1748             }
1749             else {
1750                ref_undo = -1;
1751                fprintf(stderr,"\n*** cannot realloc undo_ref\a\n") ;
1752                XBell(theDisp, 100);
1753             }
1754 
1755             discard(KeyPressMask, event);
1756             break;
1757          }
1758          else if ( buf[0]=='u' ) {
1759             if ( ref_undo > -1 ) {
1760                int   j, k;
1761                float f0 = fft_mag, f1, f2, f3;
1762                if ( RWC_ideal != NULL  && RWC_ideal->len >= npoints ) {
1763                   j = ref_undo;
1764                   k = undo_ref[j].im;
1765                   f1 = r_arr[k+1].r = undo_ref[j].r;
1766                   f2 = r_arr[k+1].i = undo_ref[j].i;
1767                   r_arr[FT_dim-k-1].r = undo_ref[j].r2;
1768                   r_arr[FT_dim-k-1].i = undo_ref[j].i2;
1769                   f3 = f0 * sqrt(f1*f1 + f2*f2);
1770                   if ( f3 > 32767. ) f3 = 32767.;
1771                   RWC_ideal->ts[k] = f3;
1772                   ref_undo -= 1;
1773                   undo_ref =
1774                      realloc(undo_ref,(ref_undo+1)*sizeof(struct _undo_buf));
1775                   if ( undo_ref == NULL ) {
1776                      ref_undo = -1;
1777                      fprintf(stderr, "\n*** cannot realloc undo_ref\a\n") ;
1778                      XBell(theDisp, 100);
1779                   }
1780                }
1781             }
1782             if ( act_undo > -1 ) {
1783                int   i, j, k;
1784                float f0 = fft_mag, f1, f2, f3;
1785                for ( i=0, j = act_undo; i < ar_size; i++, j--) {
1786                   Im_Nr = undo_buf[j].im;
1787                   k = undo_buf[j].pix;
1788                   f1 = c_arr[k*FT_dim+Im_Nr+1].r = undo_buf[j].r;
1789                   f2 = c_arr[k*FT_dim+Im_Nr+1].i = undo_buf[j].i;
1790                   c_arr[(k+1)*FT_dim-Im_Nr-1].r  = undo_buf[j].r2;
1791                   c_arr[(k+1)*FT_dim-Im_Nr-1].i  = undo_buf[j].i2;
1792                   f3 = f0 * sqrt(f1*f1 + f2*f2);
1793                   if ( f3 > 32767. ) f3 = 32767.;
1794                   SAR(Im_Nr)[k] = f3;
1795                }
1796 
1797                act_undo -= ar_size;
1798                undo_buf=realloc(undo_buf,(act_undo+1)*sizeof(struct _undo_buf));
1799 
1800                if ( undo_buf != NULL ) {
1801                   redraw_graph() ;
1802                   DrawSubWindow();
1803 
1804                }
1805                else {
1806                   act_undo = -1;
1807                   fprintf(stderr,
1808                           "\n*** cannot realloc undo_buf or undo_ref\a\n") ;
1809                   XBell(theDisp, 100);
1810                }
1811             }
1812 
1813             discard(KeyPressMask, event);
1814             break;
1815          }
1816          else if ( buf[0]=='U' ) {
1817             int   j, k;
1818             float f0 = fft_mag, f1, f2, f3;
1819             for (j=act_undo; j >= 0; j--) {
1820                Im_Nr = undo_buf[j].im;
1821                k = undo_buf[j].pix;
1822                f1 = c_arr[k*FT_dim+Im_Nr+1].r = undo_buf[j].r;
1823                f2 = c_arr[k*FT_dim+Im_Nr+1].i = undo_buf[j].i;
1824                c_arr[(k+1)*FT_dim-Im_Nr-1].r  = undo_buf[j].r2;
1825                c_arr[(k+1)*FT_dim-Im_Nr-1].i  = undo_buf[j].i2;
1826                f3 = f0 * sqrt(f1*f1 + f2*f2);
1827                if ( f3 > 32767. ) f3 = 32767.;
1828                SAR(Im_Nr)[k] = f3;
1829             }
1830             if ( RWC_ideal != NULL  && RWC_ideal->len >= npoints ) {
1831                for (j=ref_undo; j >= 0; j--) {
1832                   k = undo_ref[j].im;
1833                   f1 = r_arr[k+1].r = undo_ref[j].r;
1834                   f2 = r_arr[k+1].i = undo_ref[j].i;
1835                   r_arr[FT_dim-k-1].r  = undo_ref[j].r2;
1836                   r_arr[FT_dim-k-1].i  = undo_ref[j].i2;
1837                   f3 = f0 * sqrt(f1*f1 + f2*f2);
1838                   if ( f3 > 32767. ) f3 = 32767.;
1839                   RWC_ideal->ts[k] = f3;
1840                }
1841                free(undo_ref);
1842                ref_undo = -1;
1843             }
1844             free(undo_buf);
1845             act_undo = -1;
1846             redraw_graph();
1847             DrawSubWindow();
1848             discard(KeyPressMask, event);
1849             break;
1850          }
1851       }
1852       else {    /* no FT1_pressed */
1853          if ( ks == XK_Right ) {
1854             int max_im, i_tmp = Im_Nr;
1855             int aaa = avr_grp, ddd = diff_im;
1856 
1857             max_im = npoints - Av_length;
1858 
1859             if ( Im_Nr >= npoints ) {
1860                if ( Im_Nr < (N_im - 1) ) Im_Nr += 1;
1861             }
1862             else if ( Im_Nr < max_im ) Im_Nr += 1;
1863             else if ( npoints < N_im ) {
1864                avr_grp = 0;
1865                diff_im = 0;
1866                Im_Nr = npoints;
1867             }
1868             if ( i_tmp != Im_Nr ) {
1869                redraw =  avr_grp * 4 + (aaa - avr_grp) *2 + ddd - diff_im;
1870                XClearWindow(theDisp, GWindow);
1871                Put_image(Im_Nr);
1872                if ( redraw ) redraw_graph();
1873                DrawSubWindow();
1874                DrawTopWindow();
1875                discard(KeyPressMask, event);
1876             }
1877             break;
1878          }
1879          else if ( ks == XK_Left ) {
1880             int min_im = 0, i_tmp = Im_Nr;
1881             int aaa = avr_grp, ddd = diff_im;
1882 
1883             if ( Im_Nr > npoints ) Im_Nr -= 1;
1884             else {
1885                diff_im = fim_dif;
1886                avr_grp = fim_avr;
1887                if(Im_Nr > min_im) Im_Nr -= 1;
1888                if ( avr_grp )
1889                   if ( Im_Nr > (npoints - Av_length) )
1890                      Im_Nr = npoints - Av_length;
1891             }
1892             if ( i_tmp != Im_Nr ) {
1893                redraw =  avr_grp * 4 + (aaa - avr_grp) *2 + ddd - diff_im;
1894                XClearWindow(theDisp, GWindow);
1895                Put_image(Im_Nr);
1896                if ( redraw ) redraw_graph();
1897                DrawSubWindow();
1898                DrawTopWindow();
1899                discard(KeyPressMask, event);
1900             }
1901             break;
1902          }
1903       }
1904 
1905 
1906       if ( (I_lck == 1) && (buf[0] == 13) ) { /* make image number */
1907          if ( tmp_Nr >= 0 ) {
1908             int aaa = avr_grp, ddd = diff_im;
1909 
1910             if ( tmp_Nr > 0 ) Im_Nr = min(N_im - 1, tmp_Nr - 1);
1911             New_Cursor(theDisp, theWindow, XC_left_ptr, "red", "white");
1912             New_Cursor(theDisp,   GWindow, XC_left_ptr, "blue", "yellow");
1913             XClearWindow(theDisp, GWindow);
1914             diff_im = fim_dif;
1915             avr_grp = fim_avr;
1916             if ( Im_Nr >= npoints ) {
1917                avr_grp = 0;
1918                diff_im = 0;
1919             }
1920             else
1921                if ( Im_Nr > npoints - Av_length )
1922                   Im_Nr = npoints - Av_length;
1923             redraw =  avr_grp * 4 + (aaa - avr_grp) *2 + ddd - diff_im;
1924             Put_image(Im_Nr);
1925             if ( redraw ) redraw_graph();
1926             DrawSubWindow();
1927             DrawTopWindow();
1928             I_lck = 0;
1929             tmp_Nr = 0;
1930          }
1931          break;
1932       }
1933       if ( (N_lck == 1) && (buf[0] == 13) ) { /* make grid resol. number */
1934          if ( tmp_Nr >= 0 ) {
1935             if ( tmp_Nr > 0 ) {
1936                matx = min(MAT_MAX, tmp_Nr);
1937                maty = min(MAT_MAX, tmp_Nr);
1938             }
1939             New_Cursor(theDisp, theWindow, XC_left_ptr, "red", "white");
1940             New_Cursor(theDisp,   GWindow, XC_left_ptr, "blue", "yellow");
1941             if ( (matx != matx_0) && (maty != maty_0) ) {
1942                init_mat(0);
1943                redraw_graph();
1944             }
1945 	    RWC_framehide = 0 ;
1946             Put_image(Im_Nr);
1947             DrawSubWindow();
1948             N_lck = 0;
1949             tmp_Nr = 0;
1950          }
1951          break;
1952       }
1953       if ( (I_lck == 1) || (N_lck == 1) ) {   /* make a number from digits */
1954          if ( isdigit(buf[0]) ) {
1955             i = buf[0] - 48;
1956             tmp_Nr = min(10000, 10*tmp_Nr + i);
1957          }
1958          break;
1959       }
1960       else {
1961          switch (buf[0]) {
1962             /* make time course array of the sum of several pixels */
1963             case 'a': {
1964                int i, index;
1965                if ( FT_graph_on ) {
1966                   if ( avr_A == NULL ) {
1967                      avr_A = (float *) malloc(t_points*sizeof(float));
1968                      if( avr_A == NULL ){
1969                         fprintf(stderr,"\n*** cannot malloc avr_A\a\n") ;
1970                         XBell(theDisp, 100); break;
1971                      }
1972                      else {
1973                         for (i=0; i < t_points; i++) avr_A[i] = 0.;
1974                      }
1975                      avr_nr = 0;
1976                   }
1977                   index = ypoint*im_size+xpoint;
1978                   for (i=0; i < t_points; i++)
1979                      avr_A[i] += (float) T_SAR(i)[index];
1980                   avr_nr++;
1981                }
1982                discard(KeyPressMask, event);
1983                break ;
1984             }
1985             case 'e': {  /* average to the last pixel */
1986                int i, index = ar_size - 1;
1987                float f0;
1988                if ( FT_graph_on && (avr_A != NULL) ) {
1989                   if ( avr_nr > 0 ) {
1990                      f0 = 1. / (float) avr_nr;
1991                      for (i=0; i < t_points; i++) {
1992                         T_SAR(i)[index-allim[0]->nx] =
1993                         T_SAR(i)[index] = f0 * avr_A[i];
1994                      }
1995 printf(" t_points = %d, avr_nr = %d\n", t_points, avr_nr);
1996                      free(avr_A);
1997                      avr_nr = 0;
1998                      cancell_FT = 1;
1999                   }
2000                }
2001                discard(KeyPressMask, event);
2002                break ;
2003             }
2004             case '~': {
2005                save_all_images();
2006                break;
2007             }
2008             case '^': {
2009                New_Cursor(theDisp, theWindow, XC_left_ptr, "red", "white");
2010                break;
2011             }
2012             case 's': {
2013                c_swap();
2014                break;
2015             }
2016             case 'S': {
2017                save_act_im();
2018                discard(KeyPressMask, event);
2019                break;
2020             }
2021             case 'X': {          /* AAJ tmp to save average array as is */
2022                save_avr_array();
2023                discard(KeyPressMask, event);
2024                break;
2025             }
2026             case 'f': {
2027                if ( FT_graph_on ) get_fft_mag(&fft_mag);
2028                discard(KeyPressMask, event);
2029                break ;
2030             }
2031             case 'F': {
2032                read_new_im() ;
2033                discard(KeyPressMask, event);
2034                break ;
2035             }
2036             case 'K': {
2037                kill_curr_im() ;
2038                discard(KeyPressMask, event);
2039                break ;
2040             }
2041             case 'A': {
2042                RWC_autoscale = ! RWC_autoscale ;
2043                old_im = -1 ;
2044                Put_image( Im_Nr ) ;
2045                discard(KeyPressMask, event);
2046                break ;
2047             }
2048             case 'h': {
2049                RWC_framehide = ! RWC_framehide ;
2050                Put_image( Im_Nr ) ;
2051                break ;
2052             }
2053             case 'H': {
2054                RWC_overhide = ! RWC_overhide ;
2055                Put_image( Im_Nr ) ;
2056                break ;
2057             }
2058 	    case 'O': {
2059                RWC_checker  = ! RWC_checker ;
2060 	       RWC_overhide = 0 ;
2061                Put_image( Im_Nr ) ;
2062 	       break ;
2063             }
2064             case 'C': {
2065                YES_color = 1;
2066                colmap_init();
2067                break;
2068             }
2069             case 'B': {
2070                YES_color = 0;
2071                colmap_init();
2072                break;
2073             }
2074 #ifdef USE_MCW
2075             case '0': {
2076                Put_image(-1) ;
2077                sleep(1) ;
2078                Put_image(Im_Nr) ;
2079                discard(KeyPressMask, event);
2080                break ;
2081             }
2082 #endif
2083             case '1':   /* move to image with this number */
2084 	    case '2':
2085 	    case '3':
2086 	    case '4':
2087 	    case '5':
2088 	    case '6':
2089             case '7':
2090 	    case '8':
2091 	    case '9': {
2092                int aaa = avr_grp, ddd = diff_im , itmp;
2093 
2094                itmp = buf[0] - '1' ; if( itmp >= N_im ) itmp = N_im - 1 ;
2095 
2096                /* past time course => no averaging, etc */
2097                if( itmp >= npoints ) {
2098                   avr_grp = 0;
2099                   diff_im = 0;
2100                }
2101                else {
2102                   diff_im = fim_dif;
2103                   avr_grp = fim_avr;
2104                   if( itmp > npoints-Av_length ) itmp = npoints - Av_length;
2105                }
2106 	       if( itmp != Im_Nr ){
2107 		  Im_Nr = itmp ;
2108                   redraw =  avr_grp * 4 + (aaa - avr_grp) *2 + ddd - diff_im;
2109 
2110                   XClearWindow(theDisp, GWindow);
2111                   Put_image(Im_Nr);
2112                   if ( redraw ) redraw_graph();
2113                   DrawSubWindow();
2114                   DrawTopWindow();
2115                }
2116                discard(KeyPressMask, event);
2117                break;
2118             }
2119             case 'L':
2120             case 'l': {
2121                int max_im ;
2122                int aaa = avr_grp, ddd = diff_im;
2123 
2124                if( buf[0] == 'L' ) max_im = npoints - 1 ;
2125                else                max_im = N_im - 1 ;
2126 
2127                if ( max_im >= npoints ) {
2128                   avr_grp = 0;
2129                   diff_im = 0;
2130                }
2131                else {
2132                   diff_im = fim_dif;
2133                   avr_grp = fim_avr;
2134                   max_im = npoints - Av_length;
2135                }
2136                redraw =  avr_grp * 4 + (aaa - avr_grp) *2 + ddd - diff_im;
2137                Im_Nr = max_im;
2138                XClearWindow(theDisp, GWindow);
2139                Put_image(Im_Nr);
2140                if ( redraw ) redraw_graph();
2141                DrawSubWindow();
2142                DrawTopWindow();
2143                discard(KeyPressMask, event);
2144                break;
2145             }
2146             case '>': {
2147                int max_im, i_tmp = Im_Nr;
2148                int aaa = avr_grp, ddd = diff_im;
2149 
2150                max_im = npoints - Av_length;
2151 
2152                if ( Im_Nr >= npoints ) {
2153                   if ( Im_Nr < (N_im - 1) ) Im_Nr += 1;
2154                }
2155                else if ( Im_Nr < max_im ) Im_Nr += 1;
2156                else if ( npoints < N_im ) {
2157                   avr_grp = 0;
2158                   diff_im = 0;
2159                   Im_Nr = npoints;
2160                }
2161                if ( i_tmp != Im_Nr ) {
2162                   redraw =  avr_grp * 4 + (aaa - avr_grp) *2 + ddd - diff_im;
2163                   XClearWindow(theDisp, GWindow);
2164                   Put_image(Im_Nr);
2165                   if ( redraw ) redraw_graph();
2166                   DrawSubWindow();
2167                   DrawTopWindow();
2168                   discard(KeyPressMask, event);
2169                }
2170                break;
2171             }
2172             case '<': {
2173                int min_im = 0, i_tmp = Im_Nr;
2174                int aaa = avr_grp, ddd = diff_im;
2175 
2176 #ifdef USE_MCW
2177                if( Im_Nr == 0 ){
2178                   Put_image(-1) ;
2179                   sleep(1) ;
2180                   Put_image(0) ;
2181                   discard(KeyPressMask, event);
2182                   break ;
2183                }
2184 #endif
2185 
2186                if ( Im_Nr > npoints ) Im_Nr -= 1;
2187                else {
2188                   diff_im = fim_dif;
2189                   avr_grp = fim_avr;
2190                   if(Im_Nr > min_im) Im_Nr -= 1;
2191                   if ( avr_grp )
2192                      if ( Im_Nr > (npoints - Av_length) )
2193                         Im_Nr = npoints - Av_length;
2194                }
2195                if ( i_tmp != Im_Nr ) {
2196                   redraw =  avr_grp * 4 + (aaa - avr_grp) *2 + ddd - diff_im;
2197                   XClearWindow(theDisp, GWindow);
2198                   Put_image(Im_Nr);
2199                   if ( redraw ) redraw_graph();
2200                   DrawSubWindow();
2201                   DrawTopWindow();
2202                   discard(KeyPressMask, event);
2203                }
2204                break;
2205             }
2206                    /* + and - keys used for adjusting scale */
2207             case '-': {
2208                scale_down();
2209                redraw_graph();
2210                DrawSubWindow();
2211                break;
2212             }
2213             case '+': {
2214                scale_up();
2215                redraw_graph();
2216                DrawSubWindow();
2217                break;
2218             }
2219             case 'b': {
2220                RWC_groupbase = ! RWC_groupbase ;
2221                redraw_graph();
2222                DrawSubWindow();
2223                break;
2224             }
2225             case 'x': {
2226                AJ_base = ! AJ_base;
2227                redraw_graph();
2228                DrawSubWindow();
2229                break;
2230             } /* p used to write plot to file */
2231             case 'w': case 'p': {
2232                int ask_file = (buf[0] == 'p') ;
2233 
2234                print_plot(ask_file);
2235                discard(KeyPressMask, event);
2236                break;
2237             }
2238                    /* m and M keys used for adjusting matrix */
2239             case 'm': {
2240                mat_down(0);
2241                discard(KeyPressMask, event);
2242                break;
2243             }
2244             case 'M': {
2245                mat_up(0);
2246                discard(KeyPressMask, event);
2247                break;
2248             }
2249             case 't': {
2250                Time_avr = ! Time_avr;
2251                redraw_graph();
2252                DrawSubWindow();
2253                discard(KeyPressMask, event);
2254                break;
2255             }
2256             case 'v': {
2257                mat_down(1);
2258                discard(KeyPressMask, event);
2259                break;
2260             }
2261             case 'V': {
2262                mat_up(1);
2263                discard(KeyPressMask, event);
2264             }
2265                    /* g and G keys used for adjusting grid lines */
2266             case 'g': {
2267                grid_down();
2268                discard(KeyPressMask, event);
2269                break;
2270             }
2271             case 'G': {
2272                grid_up();
2273                discard(KeyPressMask, event);
2274                break;
2275             }
2276             case 'r': {
2277                color_index++;
2278                if (color_index >= COL_NUM) color_index = -1;
2279                if (color_index < 1) mark = 1 - mark;
2280                redraw_graph();
2281                DrawSubWindow();
2282                discard(KeyPressMask, event);
2283                break;
2284             }
2285             case 'R': {
2286                fr_index--;
2287                if (fr_index < -16){
2288                   fr_index = -1;
2289 #ifdef USE_MCW
2290                   Put_image(-1) ;
2291 #endif
2292 	       }
2293 	       RWC_framehide = 0 ;
2294                Put_image(Im_Nr);
2295                discard(KeyPressMask, event);
2296                break;
2297             }
2298             case 'd': {
2299                int xx, index = ypoint*im_size+xpoint;
2300                xx = (int) (SAR(Im_Nr)[index]) - 3600;
2301                if ( xx > 32767 ) SAR(Im_Nr)[index] = 32767;
2302                else              SAR(Im_Nr)[index] = xx;
2303                redraw_graph() ;
2304                DrawSubWindow();
2305                old_im = -1;
2306                Put_image(Im_Nr);
2307                discard(KeyPressMask, event);
2308                break;
2309             }
2310             case 'D': {
2311                int xx, index = ypoint*im_size+xpoint;
2312                xx = (int) (SAR(Im_Nr)[index]) + 3600;
2313                if ( xx < -32768 ) SAR(Im_Nr)[index] = -32768;
2314                else               SAR(Im_Nr)[index] = xx;
2315                redraw_graph() ;
2316                DrawSubWindow();
2317                old_im = -1;
2318                Put_image(Im_Nr);
2319                discard(KeyPressMask, event);
2320                break;
2321             }
2322 
2323          }
2324       } /* end I_lck = 0 */
2325 
2326    }  /* end of KeyPress */
2327    break;
2328 
2329    case ButtonPress: {
2330       XButtonPressedEvent *b = (XButtonPressedEvent *) event;
2331       int delta = 1;
2332 
2333       wind = b->window;
2334       if (wind == theWindow ) {
2335 
2336          if (b->button == Button1 && repeat_status == 0) {
2337             if (b->x > eWIDE) break;
2338             B1_action = 1;
2339             Track_Cursor(b->x, b->y);
2340             discard(ButtonPressMask, event);
2341             break;
2342          }
2343 
2344          if ( b->button == Button2 ) {        /* contrast and brightness */
2345             repeat_status = 1;
2346             if ( C_count <= 0 ) {
2347                if (b->x <   eWIDE/3) {
2348                   c_squeeze( delta);
2349                }
2350                if ((b->x > 2*eWIDE/3) && (b->x < eWIDE)) {
2351                   c_squeeze(-delta);
2352                }
2353                if ((b->y <   eHIGH/3) && (b->x < eWIDE)) {
2354                   c_bright(-delta);
2355                }
2356                if ((b->y > 2*eHIGH/3) && (b->x < eWIDE)) {
2357                   c_bright( delta);
2358                }
2359                if ((b->y >   eHIGH/2) && (b->x > eWIDE) && (b->x < eWIDE+eW)) {
2360                   c_rotate(-delta);
2361                }
2362                if ((b->y <   eHIGH/2) && (b->x > eWIDE) && (b->x < eWIDE+eW)) {
2363                   c_rotate(delta);
2364                }
2365                if ( AJ_PseudoColor )
2366                   C_count = CONTRAST_CHANGE_STEP;
2367                else
2368                   C_count = 0;
2369                break;
2370             }
2371             if ( C_count > -1 ) C_count--;
2372          }
2373 
2374          if (b->button == Button3 && repeat_status == 0) {
2375             delta = 1;
2376             if (b->x <   eWIDE/3) {
2377                c_squeeze( delta); break;
2378             }
2379             if ((b->x > 2*eWIDE/3) && (b->x < eWIDE)) {
2380                c_squeeze(-delta); break;
2381             }
2382             if ((b->y <   eHIGH/3) && (b->x < eWIDE)) {
2383                c_bright(-delta); break;
2384             }
2385             if ((b->y > 2*eHIGH/3) && (b->x < eWIDE)) {
2386                c_bright( delta); break;
2387             }
2388             if ((b->y >   eHIGH/3) && (b->y < 2*eHIGH/3) &&
2389                 (b->x >   eWIDE/3) && (b->x < 2*eWIDE/3)) {
2390                if (YES_color) No_Color_init = 1;
2391                else           No_Grey_init  = 1;
2392                colmap_init(); break;
2393             }
2394             if ((b->y >   eHIGH/2) && (b->x > eWIDE) && (b->x < eWIDE + eW)) {
2395                c_rotate(-delta); break;
2396             }
2397             if ((b->y <   eHIGH/2) && (b->x > eWIDE) && (b->x < eWIDE + eW)) {
2398                c_rotate(delta); break;
2399             }
2400          }
2401       }   /* for theWindow */
2402       else if (wind == GWindow) {
2403          int i, j, kx , ky;
2404 
2405          if( (b->button == Button1) && (b->x > GL_DLX) ){
2406             kx = gx_max/matx;
2407             ky = gy_max/maty;
2408             i = (b->x - GL_DLX + kx)*matx/gx_max;
2409             j = (b->y - GT_DLY + ky)*maty/gy_max;
2410             xpoint += i - (matx + 2)/2;
2411             ypoint += j - (maty + 2)/2;
2412             if (xpoint < 0)        xpoint += im_size;
2413             if (xpoint >= im_size) xpoint -= im_size;
2414             if (ypoint < 0)        ypoint += im_size;
2415             if (ypoint >= im_size) ypoint -= im_size;
2416 
2417             if ( (xpoint == xpoint_0 ) && (ypoint == ypoint_0) ) ;
2418             else {
2419                RWC_framehide = 0 ;
2420                Put_image(Im_Nr);
2421                redraw_graph();
2422                DrawSubWindow();
2423                xpoint_0 = xpoint;
2424                ypoint_0 = ypoint;
2425             }
2426          }
2427          discard(ButtonPressMask, event);
2428          break;
2429       }   /* for GWindow */
2430       else if (wind == subWindow) {
2431          if (b->button == Button1) {
2432             if ( (abs(b->x - v_point_x) < 5 ) &&
2433                  (abs(b->y - v_point_y) < 9 ) ) {
2434                Track_Vpointer();
2435             }
2436          }
2437       }   /* for subWindow */
2438 
2439       if ( (b->button == Button1) || (b->button == Button2)
2440                                   || (b->button == Button3) ) {
2441          int  i;
2442          if( invkey < 0 ){
2443             if      (b->button == Button1) rot_direct = -1;
2444             else if (b->button == Button2) rot_direct =  0;
2445             else if (b->button == Button3) rot_direct =  1;
2446             rot_state = b->state ;
2447             for (i=0; i < N_KEYS; i++) {
2448                if (key[i].wid==wind) { InvertKey(i); invkey=i; break; }
2449             }
2450          }
2451       }   /* for keys */
2452    }   /* end of ButtonPress */
2453    break;
2454 
2455    case ButtonRelease: {
2456       XButtonReleasedEvent *b = (XButtonReleasedEvent *) event;
2457 
2458       wind = b->window;
2459 
2460       if (wind == theWindow ) {
2461          if (B1_action == 1) {
2462             B1_action = 0;
2463             xpoint = Mltx[b->x]/x_mag;
2464             ypoint = Mlty[b->y]/x_mag;
2465 
2466             if ( (xpoint == xpoint_0 ) && (ypoint == ypoint_0) ) ;
2467             else {
2468                RWC_framehide = 0 ;
2469                Put_image(Im_Nr);
2470                redraw_graph();
2471                DrawSubWindow();
2472                xpoint_0 = xpoint;
2473                ypoint_0 = ypoint;
2474             }
2475          }
2476          if (b->button == Button2) {
2477             repeat_status = 0;
2478          }
2479       }
2480       else if (wind == subWindow ) {
2481          discard_Key(wind, ButtonPressMask, event);
2482          discard_Key(wind, ButtonReleaseMask, event);
2483       }
2484       else if ( (b->button == Button1) || (b->button == Button2)
2485                                        || (b->button == Button3) ) {
2486          int i;
2487          if( invkey >= 0 ){
2488             for (i=0; i < N_KEYS; i++) {
2489                if (wind == key[i].wid) { LetGoKey(invkey); break; }
2490             }
2491             invkey = -1;
2492          }
2493          discard_Key(wind, ButtonPressMask, event);
2494          discard_Key(wind, ButtonReleaseMask, event);
2495       }
2496    }
2497    break;
2498 
2499    case ConfigureNotify: {
2500       XConfigureEvent *conf_event = (XConfigureEvent *) event;
2501       int wb;
2502       wb = conf_event->height*BELT_W/im_height;
2503       if ( (conf_event->window == theWindow) &&
2504            (conf_event->height != eHIGH)) {
2505             MResize(&expImage, &eWIDE, &eHIGH, theImage,
2506                   conf_event->height, conf_event->height);
2507             MResize(&expBelt, &eW, &eH, theBelt,
2508                   wb, conf_event->height);
2509       }
2510       else if ( (conf_event->window == GWindow) &&
2511            ((conf_event->height != idY) || (conf_event->width != idX)) ) {
2512          redo_graph_window(conf_event->width, conf_event->height);
2513       }
2514    }
2515    break;
2516 
2517    case CirculateNotify:
2518    case MapNotify:
2519    case DestroyNotify:
2520    case GravityNotify:
2521    case ReparentNotify:
2522    case UnmapNotify:
2523       break;
2524 
2525    default:      /* ignore unexpected events */
2526       break;
2527  }   /* end of switch event->type */
2528 }   /* end of HandleEvent() */
2529 
2530 /* It loads color strip made by make_belt() & adds unit color stips */
2531 /* ------------------------------------------------------------- */
2532    void
load_rect_str(idata,ipx,x,y,i1,x1,i2,x2,amin,nshade)2533    load_rect_str(idata, ipx, x, y, i1, x1, i2, x2, amin, nshade)
2534    short int idata[], ipx[];
2535    int       x, y, i1, i2, x1, x2, amin, nshade;
2536 /* ------------------------------------------------------------- */
2537 {
2538    register int i, ii, j, k;
2539    int          min0, max1;
2540    float        adel0, coef;
2541 
2542    min0 =  32767;
2543    max1 = -32768;
2544    ii = x*y;
2545    for (i=0; i < ii; i++) {
2546       if ( idata[i] < min0 ) min0 = idata[i];
2547       if ( idata[i] > max1 ) max1 = idata[i];
2548    }
2549    adel0 = max1 - min0;
2550 
2551    /* set image shades */
2552 
2553    if (adel0 < 1.) adel0 = 1.;
2554    coef = ( (float) nshade - 1. ) / adel0;
2555 
2556    k = x - i2;
2557    for (i=0; i < y; i++) {
2558       ii = i*x;
2559       for (j=0; j < i1; j++)
2560          ipx[ii+j] = -x1;
2561       for (j=x-i2; j < x; j++)
2562          ipx[ii+j] = -x2;
2563       for (j=i1; j < k; j++)
2564          ipx[ii+j] = (int) ( (float) (idata[ii+j] - min0) * coef + .5) + amin;
2565    }
2566 }
2567 
2568 /* ------------------- */       /* It makes data belt (ramp of indices) */
2569    void
make_belt(id,x,y)2570    make_belt(id, x, y)
2571    short int *id;
2572    int       x, y;
2573 /* ------------------- */
2574 {
2575    register int i, j, ii;
2576 
2577    for(i=0; i < y; i++) {
2578       ii = i*x;
2579       for(j=0; j < x; j++)
2580          id[ii+j] = x - i;
2581    }
2582 }
2583 
2584 /* ------------------------------ */ /* It resizes images universally  */
2585    void
MResize(emage,eW,eH,image,w,h)2586    MResize(emage,eW,eH,image,w,h)    /* for 12 and 8 bit planes. */
2587    int     w, h, *eW, *eH;
2588    XImage  *image,*(*emage);
2589 /* ------------------------------ */
2590 {
2591    int          lt[MAX_WIDTH], bp16;
2592    register int iy, ex, ey, iW, iH, iG, iN, w2, tmp;
2593    char         *ximag;
2594    char         *Ep, *El, *Ip, *Il, *Id;
2595 
2596     iN = image->bits_per_pixel/8;    /* 1 or 2, pointer increment */
2597     iG = image->bytes_per_line;      /* Number of bytes in line */
2598     w2 = w * iN;
2599     iW = image->width;
2600     iH = image->height;
2601     bp16 = (iN < 3) ? 16 : 32;
2602     if ( iN == 1 ) bp16 = 8;
2603     if (w==iW && h==iH) {       /* very special case */
2604         if (*emage != image) {
2605             if (*emage) XDestroyImage(*emage);
2606             *emage = image;
2607             *eW = iW;  *eH = iH;
2608         }
2609     }
2610 
2611     else {                              /* have to do some work */
2612 
2613         /* first, kill the old emage, if one exists */
2614         if (*emage && (*emage != image)) {
2615            free((*emage)->data);  (*emage)->data = NULL;
2616            XDestroyImage(*emage);
2617         }
2618 
2619         /* create emage of the appropriate size */
2620 
2621         *eW = w;  *eH = h;
2622         ximag = (char *) malloc(w2 * h);
2623 
2624         *emage = XCreateImage(theDisp, theVisual, Planes, ZPixmap, 0, ximag, w, h, bp16, w2);
2625 
2626         if (!ximag || !(*emage)) {
2627            fprintf(stderr,"ERROR: unable to create a %dx%d image\a\n",w,h);
2628            exit(1);
2629         }
2630 
2631         El = Ep = (char *) (*emage)->data;
2632         Id = (char *) image->data;
2633 
2634         /* ---- Set look up table and Reframe fast ---- */
2635 
2636         for (ex = 0; ex < w; ex++)  {
2637             tmp = (iW * ex)/w;
2638             lt[ex] = iN * tmp;
2639             Mltx[ex] = tmp;
2640         }
2641 
2642         for (ey = 0; ey < h; ey++, El += w2) {
2643             iy = (iH * ey)/h;
2644             Mlty[ey] = iy;
2645             Ep = El;
2646             Il = Id + iG * iy;
2647             for(ex = 0; ex < w; ex++, Ep += iN) {
2648                 Ip = Il + lt[ex];
2649                 if ( iN == 1 ) {
2650                    *Ep = *Ip;
2651                 }
2652                 else if ( iN == 2) {
2653                    *Ep = *Ip;
2654                    *(Ep+1) = *(Ip+1);
2655                 }
2656                 else if ( iN == 3) {
2657                    *Ep = *Ip;
2658                    *(Ep+1) = *(Ip+1);
2659                    *(Ep+2) = *(Ip+2);
2660                 }
2661                 else if ( iN == 4) {
2662                    *Ep = *Ip;
2663                    *(Ep+1) = *(Ip+1);
2664                    *(Ep+2) = *(Ip+2);
2665                    *(Ep+3) = *(Ip+3);
2666                 }
2667             }
2668         }
2669     }
2670 }
2671 
2672 /* ---------------------------- */
2673    void
Allow_smaller_im(argc,argv)2674    Allow_smaller_im(argc, argv)
2675    int  argc;
2676    char *argv[];
2677 /* ---------------------------- */
2678 {
2679    XSizeHints           hints;
2680 
2681    hints.min_height = 0;
2682    hints.min_width = 0;
2683    hints.flags = PMinSize;
2684 
2685    hints.min_aspect.x = im_height + BELT_W;
2686    hints.max_aspect.x = im_height + BELT_W;
2687    hints.min_aspect.y = im_height;
2688    hints.max_aspect.y = im_height;
2689    hints.flags |= PAspect;
2690 
2691    hints.max_height = DisplayHeight(theDisp, theScreen);
2692    hints.max_width = hints.max_height *
2693                      (im_height + BELT_W)/im_height;
2694    hints.flags |= PMaxSize;
2695    XSetStandardProperties(theDisp, theWindow, T_name, T_name, None,
2696                           argv, argc, &hints);
2697 }
2698 
2699 /* ---------------------------------- */
2700    void
CreateMainWindow(geom,argc,argv)2701    CreateMainWindow(geom, argc, argv)
2702    char *geom;
2703    int  argc;
2704    char *argv[];
2705 /* ---------------------------------- */
2706 {
2707    XClassHint           class;
2708    XSetWindowAttributes attr;
2709    unsigned int         attrmask;
2710    XSizeHints           hints;
2711    int                  mask, x, y, w, h, i;
2712 
2713    x = y = w = h = 1;
2714    mask = XParseGeometry(geom, &x, &y, (unsigned int *)&w, (unsigned int *)&h);
2715 
2716    if (mask & HeightValue) {
2717      i = im_height + BELT_W;
2718      if ( i > MAX_WIDTH ) h = (MAX_WIDTH * im_height) / i;
2719      eH = eHIGH = h;
2720      eWIDE = eHIGH;
2721      eW = eH * BELT_W / im_height;
2722      aWIDE = eWIDE + eWIDE*BELT_W/im_height;
2723    }
2724 
2725    if (mask & XValue || mask & YValue) hints.flags = USPosition;
2726    else                                hints.flags = PPosition;
2727 
2728    hints.flags |= USSize;
2729 
2730    if (mask & XValue && mask & XNegative)
2731         x = XDisplayWidth(theDisp, theScreen)-eWIDE-abs(x);
2732    if (mask & YValue && mask & YNegative)
2733         y = XDisplayHeight(theDisp, theScreen)-eHIGH-abs(y);
2734 
2735    class.res_name  = "ImageX";
2736    class.res_class = "ImageX";
2737 
2738    hints.min_aspect.x = im_height + BELT_W;
2739    hints.max_aspect.x = im_height + BELT_W;
2740    hints.min_aspect.y = im_height;
2741    hints.max_aspect.y = im_height;
2742    hints.flags |= PAspect;
2743 
2744    hints.x = x;                 hints.y = y;
2745    hints.width = aWIDE;         hints.height = eHIGH;
2746    hints.max_width = aWIDE;     hints.max_height = eHIGH;
2747    hints.flags |= PMaxSize;
2748 
2749    hints.min_width = aWIDE;     hints.min_height = eHIGH;;
2750    hints.flags |= PMinSize;
2751 
2752    attr.background_pixel = bcol;
2753    attr.border_pixel     = fcol;
2754    attrmask = CWBackPixel | CWBorderPixel;
2755 
2756    theWindow = XCreateWindow(theDisp, rootW, x, y, aWIDE, eHIGH, 2,
2757       CopyFromParent, CopyFromParent, CopyFromParent, attrmask, &attr);
2758 
2759    if (!theWindow)
2760       FatalError("Can't open window (are X11 windows running ?). AJ");
2761 
2762    XSetClassHint(theDisp, theWindow, &class);
2763    XSetStandardProperties(theDisp, theWindow, T_name, T_name, None,
2764                           argv, argc, &hints);
2765 }
2766 
2767 /* ----------------- */ /* Set color or grey array of the Image */
2768    void
colmap_init()2769    colmap_init()
2770 /* ----------------- */
2771 {
2772    if (YES_color)  color_init(COL_MIN, spectrum);
2773    else            grey_init();
2774 }
2775 
2776 /* -------------------- */       /* Set grey array of the Image  */
2777    void
grey_init()2778    grey_init()
2779 /* -------------------- */
2780 {
2781    register int i, k, m;
2782    float a;
2783 
2784    a = 200./ncolors;
2785 
2786    if (No_Grey_init) {
2787       for (i=0; i < ncolors; i++) {
2788          k = 255.*pow((a*i+55.)/255., gamm) + .5;
2789          m = min_max_col(k << 8);
2790          INgrey[i] = m;
2791          MYgrey[i].pixel = pixels[i];
2792          MYgrey[i].red   = m;
2793          MYgrey[i].green = m;
2794          MYgrey[i].blue  = m;
2795          MYgrey[i].flags = DoRed|DoGreen|DoBlue;
2796       }
2797       No_Grey_init = 0;
2798    }
2799    if ( AJ_PseudoColor ) XStoreColors(theDisp, CMap, MYgrey, ncolors);
2800    else                AJ_StoreColors(theDisp, CMap, MYgrey, ncolors, 0);
2801 }
2802 
2803 /* ----------------- */ /* Set color array of the Image */
2804    void
color_init(a1,a2)2805    color_init(a1,a2)    /* OK but sharp edge on green near yellow */
2806    int a1, a2;
2807 /* ----------------- */
2808 {
2809    double da, an, c, n, s, sb, cb, ak, ab;
2810    register int i, m, r=0, g=0, b=0;
2811 
2812    if (No_Color_init) {
2813       FIRST = 1;        SQUE_NR = ncolors;
2814       n = ncolors;
2815       ak = 105.; s = 150.; c = s/60.;
2816       ab = 65.; sb = 190.; cb = s/60.;
2817       m=256;
2818       an = a1;
2819       da = a2 - a1;     da = da/n;
2820       an = an-da+360.;
2821 
2822       for(i=0; i < ncolors; i++) {
2823         an += da;   an=fmod(an,360.);
2824         if((an >= 0) && (an < 120.)) {
2825           r = 255.*pow((ak + min(s,(120. - an)*c))/255., gamm) +.5;
2826           g = 255.*pow((ak + min(s,an*c))/255., gamm) +.5;
2827           b=0;
2828         }
2829         if((an >= 120.) && (an < 240.)) {
2830           r = 0;
2831           g = 255.*pow((ak + min(s ,(240. - an)*c))/255., gamm) +.5;
2832           b = 255.*pow((ab + min(sb,(an - 120.)*cb))/255., gamm) +.5;
2833         }
2834         if(an >= 240.) {
2835           r =  255.*pow((ak + min(s,(an - 240.)*c))/255., gamm) +.5;
2836           g = 0;
2837           b = 255.*pow((ak + min(s,(360. - an)*c))/255., gamm) +.5;
2838         }
2839         MYcol[i].pixel = pixels[ncolors-1-i];
2840         MYcol[i].red   = r*m;
2841         MYcol[i].green = g*m;
2842         MYcol[i].blue  = b*m;
2843         MYcol[i].flags = DoRed|DoGreen|DoBlue;
2844       }
2845       No_Color_init = 0;
2846    }
2847    if ( AJ_PseudoColor ) XStoreColors(theDisp, CMap, MYcol, ncolors);
2848    else                AJ_StoreColors(theDisp, CMap, MYcol, ncolors, 1);
2849 }
2850 
2851 /* --------------- */
2852    void
c_rotate(k)2853    c_rotate(k)
2854    int k;
2855 /* --------------- */
2856 {
2857    if (YES_color) color_rotate(k);
2858    else           grey_rotate(-k);
2859 }
2860 
2861 
2862 /* --------------- */
2863    void
color_rotate(k)2864    color_rotate(k)
2865    int k;
2866 /* --------------- */
2867 {
2868    register int i, j;
2869 
2870    FIRST = 1;
2871    SQUE_NR = ncolors;
2872 
2873 
2874    if(k >= 0) {
2875      for(i=0; i < k; i++) {
2876      tmp1[i] = MYcol[i].red;
2877      tmp2[i] = MYcol[i].green;
2878      tmp3[i] = MYcol[i].blue;
2879      }
2880      for(i=0; i < ncolors - k; i++) {
2881        MYcol[i].red   = MYcol[i+k].red;
2882        MYcol[i].green = MYcol[i+k].green;
2883        MYcol[i].blue  = MYcol[i+k].blue;
2884      }
2885      for(i = ncolors - k, j = 0; i < ncolors; i++, j++) {
2886        MYcol[i].red   = tmp1[j];
2887        MYcol[i].green = tmp2[j];
2888        MYcol[i].blue  = tmp3[j];
2889      }
2890    }
2891    else {
2892      k = -k;
2893      for(i = ncolors - 1; i >= ncolors - k; i--) {
2894      tmp1[i] = MYcol[i].red;
2895      tmp2[i] = MYcol[i].green;
2896      tmp3[i] = MYcol[i].blue;
2897      }
2898      for(i = ncolors - 1; i >= k; i--) {
2899        MYcol[i].red   = MYcol[i-k].red;
2900        MYcol[i].green = MYcol[i-k].green;
2901        MYcol[i].blue  = MYcol[i-k].blue;
2902      }
2903      for(i = k-1, j = ncolors - 1; i >=0; i--, j--) {
2904        MYcol[i].red   = tmp1[j];
2905        MYcol[i].green = tmp2[j];
2906        MYcol[i].blue  = tmp3[j];
2907      }
2908    }
2909    if ( AJ_PseudoColor ) XStoreColors(theDisp, CMap, MYcol, ncolors);
2910    else                AJ_StoreColors(theDisp, CMap, MYcol, ncolors, 1);
2911 }
2912 
2913 /* --------------- */
2914    void
grey_rotate(k)2915    grey_rotate(k)
2916    int k;
2917 /* --------------- */
2918 {
2919    register int i, j;
2920 
2921    FIRST = 1;
2922    SQUE_NR = ncolors;
2923 
2924 
2925    if(k >= 0) {
2926      for(i=0; i < k; i++) {
2927      tmp1[i] = MYgrey[i].red;
2928      tmp2[i] = MYgrey[i].green;
2929      tmp3[i] = MYgrey[i].blue;
2930      }
2931      for(i=0; i < ncolors - k; i++) {
2932        MYgrey[i].red   = MYgrey[i+k].red;
2933        MYgrey[i].green = MYgrey[i+k].green;
2934        MYgrey[i].blue  = MYgrey[i+k].blue;
2935      }
2936      for(i = ncolors - k, j = 0; i < ncolors; i++, j++) {
2937        MYgrey[i].red   = tmp1[j];
2938        MYgrey[i].green = tmp2[j];
2939        MYgrey[i].blue  = tmp3[j];
2940      }
2941    }
2942    else {
2943      k = -k;
2944      for(i = ncolors - 1; i >= ncolors - k; i--) {
2945      tmp1[i] = MYgrey[i].red;
2946      tmp2[i] = MYgrey[i].green;
2947      tmp3[i] = MYgrey[i].blue;
2948      }
2949      for(i = ncolors - 1; i >= k; i--) {
2950        MYgrey[i].red   = MYgrey[i-k].red;
2951        MYgrey[i].green = MYgrey[i-k].green;
2952        MYgrey[i].blue  = MYgrey[i-k].blue;
2953      }
2954      for(i = k-1, j = ncolors - 1; i >=0; i--, j--) {
2955        MYgrey[i].red   = tmp1[j];
2956        MYgrey[i].green = tmp2[j];
2957        MYgrey[i].blue  = tmp3[j];
2958      }
2959    }
2960    if ( AJ_PseudoColor ) XStoreColors(theDisp, CMap, MYgrey, ncolors);
2961    else                AJ_StoreColors(theDisp, CMap, MYgrey, ncolors, 0);
2962 }
2963 
2964 /* -------- */
2965    void
c_swap()2966    c_swap()
2967 /* -------- */
2968 {
2969    if (YES_color) color_swap();
2970 }
2971 
2972 /* --------------- */
2973    void
color_swap()2974    color_swap()
2975 /* --------------- */
2976 {
2977    register int i, k;
2978 
2979    FIRST = 1; SQUE_NR = ncolors;
2980    k = ncolors - 1;
2981 
2982    for(i=0; i < ncolors; i++) {
2983     tmp1[i] = MYcol[i].red;
2984     tmp2[i] = MYcol[i].green;
2985     tmp3[i] = MYcol[i].blue;
2986    }
2987    for(i=0; i < ncolors ; i++) {
2988      MYcol[i].red   = tmp1[k-i];
2989      MYcol[i].green = tmp2[k-i];
2990      MYcol[i].blue  = tmp3[k-i];
2991    }
2992    if ( AJ_PseudoColor ) XStoreColors(theDisp, CMap, MYcol, ncolors);
2993    else                AJ_StoreColors(theDisp, CMap, MYcol, ncolors, 1);
2994 }
2995 
2996 /* ------------- */ /* Modify span or contrast */
2997    void
c_squeeze(d)2998    c_squeeze(d)
2999    int d;
3000 /* ------------- */
3001 {
3002    if (YES_color) color_squeeze(d);
3003    else           grey_contrast(-2*d);
3004 }
3005 
3006 /* -------------------- */      /* Modify contrast of the Image */
3007    void
grey_contrast(d_lev)3008    grey_contrast(d_lev)
3009    int d_lev;
3010 /* -------------------- */
3011 {
3012    register int i, k, m, delta, dx;
3013 
3014    dx = max(((abs(INgrey[ncolors-1] - INgrey[0])>>6)/ncolors), 1);
3015    delta = d_lev*dx;
3016    for(i=0; i < ncolors; i++) {
3017       k = INgrey[i] += i*delta;
3018       m = min_max_col(k);
3019       MYgrey[i].red   = m;
3020       MYgrey[i].green = m;
3021       MYgrey[i].blue  = m;
3022    }
3023    if ( AJ_PseudoColor ) XStoreColors(theDisp, CMap, MYgrey, ncolors);
3024    else                AJ_StoreColors(theDisp, CMap, MYgrey, ncolors, 0);
3025 }
3026 
3027 /* -------------------- */ /* Modify span of colors*/
3028    void
color_squeeze(d)3029    color_squeeze(d)
3030    int d;
3031 /* -------------------- */
3032 {
3033    static unsigned int x_arr[NCOLORS];
3034    register int i, ex, w;
3035 
3036    w = ncolors/2;
3037    SQUE_NR = max(1, SQUE_NR - d);
3038    for (ex = 0; ex < ncolors; ex++)  x_arr[ex] = SQUE_NR*(ex - w)/ncolors + w;
3039 
3040    if(FIRST)
3041    for(i=0; i < ncolors; i++) {
3042      tmp1[i] = MYcol[i].red;
3043      tmp2[i] = MYcol[i].green;
3044      tmp3[i] = MYcol[i].blue;
3045      FIRST = 0;
3046    }
3047    for(i=0; i < ncolors; i++) {
3048      if(x_arr[i] > uucolors) {
3049        MYcol[i].red   = 0;
3050        MYcol[i].green = 0;
3051        MYcol[i].blue  = 0;
3052      }
3053      else {
3054        MYcol[i].red   = tmp1[x_arr[i]];
3055        MYcol[i].green = tmp2[x_arr[i]];
3056        MYcol[i].blue  = tmp3[x_arr[i]];
3057      }
3058    }
3059    if ( AJ_PseudoColor ) XStoreColors(theDisp, CMap, MYcol, ncolors);
3060    else                AJ_StoreColors(theDisp, CMap, MYcol, ncolors, 1);
3061 }
3062 
3063 /* ------------------ */ /* Modify brightness (color or B&W) */
3064    void
c_bright(d)3065    c_bright(d)
3066    int d;
3067 /* ------------------ */
3068 {
3069    if (YES_color) color_bright(d);
3070    else           grey_change(-2*d);
3071 }
3072 
3073 /* ------------------ */   /* Modify brightness of the Image  */
3074    void
grey_change(d_lev)3075    grey_change(d_lev)
3076    int d_lev;
3077 /* ------------------ */
3078 {
3079    register int i, k, m, delta, dx;
3080 
3081    dx = abs((INgrey[ncolors-1] - INgrey[0])/ncolors);
3082    delta = d_lev*dx;
3083    for (i=0; i < ncolors; i++) {
3084       k = INgrey[i] += delta;
3085       m = min_max_col(k);
3086       MYgrey[i].red   = m;
3087       MYgrey[i].green = m;
3088       MYgrey[i].blue  = m;
3089    }
3090    if ( AJ_PseudoColor ) XStoreColors(theDisp, CMap, MYgrey, ncolors);
3091    else                AJ_StoreColors(theDisp, CMap, MYgrey, ncolors, 0);
3092 }
3093 
3094 /* ------------------ */ /* Modify brightness of the Image */
3095    void
color_bright(d)3096    color_bright(d)
3097    int d;
3098 /* ------------------ */
3099 {
3100    double c;
3101    register int i;
3102    c = d; c = 1. - c*.005;
3103    FIRST = 1; SQUE_NR = ncolors;
3104 
3105    for(i=0; i < ncolors; i++) {
3106      MYcol[i].red   = min_max_col(c*MYcol[i].red);
3107      MYcol[i].green = min_max_col(c*MYcol[i].green);
3108      MYcol[i].blue  = min_max_col(c*MYcol[i].blue);
3109    }
3110    if ( AJ_PseudoColor ) XStoreColors(theDisp, CMap, MYcol, ncolors);
3111    else                AJ_StoreColors(theDisp, CMap, MYcol, ncolors, 1);
3112 }
3113 
3114 /* -------------- */ /* It assigns index for one of standard 16 colors */
3115    int
STD_colors(cx)3116    STD_colors(cx)    /* First index is 1, last 16 (equv. to 0 - black col.). */
3117    int cx;
3118 /* -------------- */
3119 {
3120    XColor  any_col;
3121 
3122  if ( AJ_PseudoColor ) {
3123    if( cx > NUM_STD_COLORS ) return extra_color_x11[cx-NUM_STD_COLORS-1] ;
3124 
3125    if ( color_x11[cx-1] + 1 ) return(color_x11[cx-1]);
3126    else {
3127       any_col.red   = Solid_color[cx-1].red;
3128       any_col.green = Solid_color[cx-1].green;
3129       any_col.blue  = Solid_color[cx-1].blue;
3130       any_col.flags = DoRed | DoGreen | DoBlue;
3131 
3132       if ( !XAllocColor(theDisp, CMap, &any_col) )
3133          FatalError ("XAllocColor problem in STD_colors(). AJ");
3134 
3135       return( color_x11[cx-1] = any_col.pixel );
3136    }
3137  }
3138  else return 0;
3139 }
3140 
3141 /* ---------------------------------- */   /* Create Image from the im_arr */
Load_Any_Arr(im_arr,x,y)3142    XImage *Load_Any_Arr(im_arr, x, y)      /* Usage: theImage = Load_An... */
3143    short int im_arr[];                     /* indexed or RGB colors        */
3144    int       x, y;
3145 /* ---------------------------------- */
3146 {
3147    XImage    *image;
3148 
3149    if ( AJ_PseudoColor ) image = Load_Any_ind(im_arr, x, y);
3150    else                  image = Load_Any_RGB(im_arr, x, y);
3151 
3152    return image;
3153 }
3154 
3155 /* ---------------------------------- */   /* Create Image from the im_arr */
Load_Any_RGB(im_arr,x,y)3156    XImage *Load_Any_RGB(im_arr, x, y)      /* Indices for RGB screen       */
3157    short int im_arr[];
3158    int       x, y;
3159 /* ---------------------------------- */
3160 {
3161    register int   i, k;
3162    int        Width, Hight, last;
3163    char      *Image;
3164    XImage    *image;
3165    unsigned char  *a8, *i8, *m8;
3166    unsigned short *a16, *i16;
3167    unsigned int   *a32, *i32;
3168 
3169    Width = x;      /* Image width  */
3170    Hight = y;      /* Image higth  */
3171    last  = x * y;
3172 
3173    for (i=0; i < last; i++)
3174       if ( im_arr[i] < 0 ) im_arr[i] = STD_indx[-im_arr[i]-1];
3175 
3176    image = XCreateImage(theDisp, theVisual, Planes, ZPixmap, 0, NULL,
3177                                 Width, Hight, 32, 0);
3178    if (! image) FatalError("Unable create image in Load_R_G_B_Arr().");
3179 
3180    Image = (char *) malloc(image->bytes_per_line*Hight);
3181    if (!Image) FatalError("Not enough memory for the Image");
3182    image->data = Image;
3183 
3184    k = 0;
3185    switch( bperpix ) {
3186       case 32:
3187          a32 = (unsigned int  *) image->data;
3188          i32 = (unsigned int  *) AJ_RGB;
3189          for (i=0; i < last; i++) {
3190             *a32++ =  i32[im_arr[k++]];
3191          }
3192       break ;
3193 
3194       case 24:
3195          a8 = (unsigned char *) image->data;
3196          i8 = (unsigned char *) AJ_RGB;
3197          for (i=0; i < last; i++) {
3198             m8 =  i8 + im_arr[k++] * 3;
3199             *a8++ = *m8++;
3200             *a8++ = *m8++;
3201             *a8++ = *m8++;
3202          }
3203       break ;
3204 
3205       case 16:
3206          a16 = (unsigned short *) image->data;
3207          i16 = (unsigned short *) AJ_RGB;
3208          for (i=0; i < last; i++) {
3209             *a16++ =  i16[im_arr[k++]];
3210          }
3211       break ;
3212 
3213       case 8:
3214          a8 = (unsigned char *) image->data;
3215          i8 = (unsigned char *) AJ_RGB;
3216          for (i=0; i < last; i++) {
3217             *a8++ =  i8[im_arr[k++]];
3218          }
3219       break ;
3220    }
3221    return image;
3222 }
3223 
3224 /* ---------------------------------- */   /* Create Image from the im_arr */
Load_Any_ind(im_arr,x,y)3225    XImage *Load_Any_ind(im_arr, x, y)      /* Usage: theImage = Load_An... */
3226    short int im_arr[];                     /* Uses own 16 colors for nega- */
3227    int       x, y;                         /* tive numbers (-1 - -16).     */
3228 /* ---------------------------------- */   /* 8 and 12 bit planes work OK. */
3229 {
3230   register char *ptr;
3231   register int   i, j, k, iN, iE;
3232   int        Width, Hight;
3233   char      *Image;
3234   XImage    *image;
3235 
3236   Width = x;      /* Image width  */
3237   Hight = y;      /* Image higth  */
3238 
3239   image = XCreateImage(theDisp, theVisual, Planes, ZPixmap, 0, NULL,
3240                                 Width, Hight, 32, 0);
3241   if (! image) FatalError("Unable create image in Load_index_Arr().");
3242 
3243   Image = (char *) malloc(image->bytes_per_line*Hight);
3244   if (!Image) FatalError("Not enough memory for the Image");
3245   image->data = Image;
3246   iN = (image->bits_per_pixel + 7) / 8;    /* 1 or 2 pointer increment */
3247   iE = iN - 1;                             /* 0 or 1 for next pointer */
3248 
3249   ptr = Image;
3250   k = 0;
3251   for (i=0; i<Hight; i++)
3252      for (j=0; j<Width; j++, ptr += iN)
3253         if(im_arr[k] >= 0) {
3254           *ptr = pixels[im_arr[k]] >> 8;
3255           *(ptr + iE) = pixels[im_arr[k++]];
3256         }
3257         else {
3258           *ptr = STD_colors(-im_arr[k]) >> 8;
3259           *(ptr + iE) = STD_colors(-im_arr[k++]);
3260         }
3261 
3262   return image;
3263 }
3264 
3265 /* -------------------------------------------- */
3266    void
New_Cursor(Disp,Wind,shape,fg_col,bg_col)3267    New_Cursor(Disp, Wind, shape, fg_col, bg_col)
3268    Display     *Disp;
3269    Window       Wind;
3270    unsigned int shape;
3271    char        *fg_col, *bg_col;
3272 /* -------------------------------------------- */
3273 /* Assigns new cursor to the Window. Call after creating the Window */
3274 {
3275    XColor       Im_cur_fg, Im_cur_bg;
3276    Colormap     CM;
3277    Cursor       cursor;
3278 
3279    CM = DefaultColormap(Disp, DefaultScreen(Disp));
3280 
3281    cursor = XCreateFontCursor(Disp, shape);        /* new cursor shape */
3282    XDefineCursor(Disp, Wind, cursor);
3283    XParseColor(Disp, CM, fg_col, &Im_cur_fg);    /* forground  color */
3284    XParseColor(Disp, CM, bg_col, &Im_cur_bg);    /* background color */
3285    XRecolorCursor(Disp, cursor, &Im_cur_fg, &Im_cur_bg);
3286 }
3287 
3288 /* ----------------------------------------------------------------
3289    Read file subroutine fo use in C.        A.Jesmanowicz, MCW 1991
3290 	return error :	0 - OK,
3291 			1 - opening problem,
3292 			2 - file longer then array.
3293 	fname :	file name.
3294 	size  :	on input - max size of the arr or 0 for any length,
3295 		on output- real size of the file (and arr in bytes).
3296 	arr   :	returned file as array.
3297    ---------------------------------------------------------------- */
3298 /* ----------------------------- */
read_iqm(fname,size,arr)3299    int  read_iqm(fname,size,arr)
3300    int  *size;
3301    char fname[],arr[];
3302 /* ----------------------------- */
3303 {
3304 	int	isize = *size;
3305 	int	fp;				/* file descriptor  */
3306 	struct	stat file_stat;			/* status structure */
3307         ssize_t vv;
3308 
3309 	if ((fp = open(fname, O_RDONLY)) <= 0)	/* file must exist */
3310            return(1); 		             	/* or error = 1.   */
3311 
3312 	fstat(fp, &file_stat);			/* get file size in bytes   */
3313 
3314 	if(file_stat.st_size > isize && isize)	/* file can not be too long */
3315 	   return(2);     	                /* or error = 2.	    */
3316 
3317 	*size =  file_stat.st_size;		/* return file size */
3318 
3319 	vv = read(fp, arr, file_stat.st_size);	/* read whole file  */
3320 	close(fp);
3321 	return(0);                              /* no error : 0 */
3322 }
3323 
3324 /* ----------------------------------------------------------------
3325    Write file subroutine fo use in C.       A.Jesmanowicz, MCW 1991
3326 	return error :	0 - OK,
3327 			1 - opening problem,
3328 			2 - negative length.
3329 	fname :	file name.
3330 	size  :	size of the file.
3331 	arr   :	file array.
3332    ---------------------------------------------------------------- */
3333 /* ----------------------------- */
WRite_iqm(fname,size,arr)3334    int WRite_iqm(fname,size,arr)
3335    int  *size;
3336    char fname[],arr[];
3337 /* ----------------------------- */
3338 {
3339 	int	isize = *size;
3340 	int	fp;				/* file descriptor  */
3341         ssize_t vv;
3342 
3343 	if(isize < 0)				/* size has to be real */
3344 	   return(2);				/* or error = 2.       */
3345 
3346 	if ((fp = open(fname, O_WRONLY|O_CREAT|O_EXCL,0644)) <= 0)
3347 	   return(1);				/* file must not exist */
3348 						/* or error = 1.       */
3349 
3350 	vv = write(fp, arr, isize);		/* write whole file */
3351 	close(fp);
3352 	return(0);
3353 }
3354 
3355 
3356 /*  Directory names (if present) are skipped. and number is added in front */
3357 /* -------------- */
3358    void
top_nr_name(name)3359    top_nr_name(name)
3360    char *name;
3361 /* -------------- */
3362 {
3363    register int i, k;
3364    char         *p_name;
3365 
3366    k = strlen( name );
3367    p_name = name;
3368    for(i = 0; i < k; i++) {
3369       if(name[i] != 32 && name[i]) {
3370          if(name[i] == 47) p_name = &name[i+1];
3371       }
3372       else {
3373          name[i] = 0;
3374          break;
3375       }
3376    }
3377    sprintf(T_name, "#%d   %s", Im_Nr+1, p_name);
3378    sprintf(I_name, "G %s", p_name);
3379    sprintf(G_name, "G %s , EPI_grid", p_name);
3380 }
3381 
3382 /* ------------------ */ /* resample image into 256x256 frame using st_? */
Resample(im)3383    void Resample(im)
3384    MRI_IMAGE * im ;
3385 /* ------------------ */
3386 {
3387    register short int *a;
3388    register int       *s, i1, ix, lx, i, j, k, l, kk, mm, dkk, ii, ij, is;
3389    register int       II, J=0, IJ, IJk, ijl, k0, IM2, lx2, ly, IJK;
3390    int ndim ;
3391    short * all ;
3392 
3393    ndim = im->nx ;
3394    all  = MRI_SHORT_PTR(im) ;
3395 
3396    if(ndim == EPX4 ) {                    /* 32x32 pixels format */
3397       s  = st_8;
3398       i1 = 3;
3399       is = 6;
3400       ix = 8;
3401       lx = 32;
3402       ly = 32;
3403    }
3404    else if(ndim == EPX1 ) {                    /* 64x64 pixels format */
3405       s  = st_4;
3406       i1 = 1;
3407       is = ix = 4;
3408       lx = 64;
3409       ly = 64;
3410    }
3411    else if(ndim == EPX2) {             /* 128x128 pixels format */
3412       s  = st_2;
3413       i1 = 0;
3414       is = ix = 2;
3415       lx = 128;
3416       ly = 128;
3417    }
3418    else if ( (ndim == EPX3) || (ndim == EPX5) ) { // 256x256 or 512 pixels => no resample
3419       a = all;
3420       lx = ndim * ndim ;
3421       for (i=0; i < lx ; i++)
3422          tmp_imx[i] = imx[i] =  a[i];
3423       return;
3424    }
3425    else {
3426       printf("\n\n !!! Wrong file format in Resample() function !!!\n\n");
3427       exit(3);
3428    }
3429 
3430    /* Images of different resolutions will register for c_f=0 (and i1=0)  */
3431    /* For c_f=1 frame will be centered on the pixel!         AJ 10.18.2000 */
3432    if ( c_f == 0 ) i1 = 0;
3433 
3434    a = all;
3435 
3436    lx2 = lx*ly;
3437    IM2 = im_height*im_height;
3438    k0  = ix*(2*ix-1) - 1;
3439    dkk = 2*ix*ix;
3440 
3441    i = ly - 1;                     /* horizontal edge with wrap around */
3442    ii = i*lx;
3443    II = (i*ix+i1)*im_height + i1;
3444    for (j=0; j < lx - 1; j++) {
3445       ij  = ii+j;
3446       ijl = ij+lx;
3447       if ( ijl >= lx2 ) ijl -= lx2;
3448       IJ  = II + j*ix;
3449       for (k=0; k < ix; k++) {
3450          IJk = IJ + k*im_height ;
3451          if ( IJk >= IM2 ) IJk -= IM2;
3452          kk = k0 - ((k * ix) << 1);
3453          mm = kk + dkk;
3454          for (l=0; l < ix; l++) {
3455             tmp_imx[IJk+l]
3456               = imx[IJk+l] = ( a[ij]    * s[kk-l]
3457                              + a[ij+1]  * s[kk-l+ix]
3458                              + a[ijl]   * s[mm-l]
3459                              + a[ijl+1] * s[mm-l+ix]) >> is;
3460          }
3461       }
3462    }
3463 
3464    j = lx - 1;
3465    for (i=0; i < ly - 1; i++) {       /* vertical edge with wrap around */
3466       ii = i*lx;
3467       II = (i*ix+i1)*im_height;
3468       ij  = ii+j;
3469       ijl = ij+lx;
3470       J   = j*ix + i1;
3471       IJ  = II + J;
3472       for (k=0; k < ix; k++) {
3473          IJk = IJ + k*im_height ;
3474          kk = k0 - ((k * ix) << 1);
3475          mm = kk + dkk;
3476          for (l=0; l < ix; l++) {
3477             IJK = IJk;
3478             if ( (J + l) >= im_height ) IJK = IJk - im_height;
3479             if ( IJK >= IM2 ) IJK -= IM2;
3480             tmp_imx[IJK+l]
3481               = imx[IJK+l] = ( a[ij]      * s[kk-l]
3482                              + a[ij-lx+1] * s[kk-l+ix]
3483                              + a[ijl]     * s[mm-l]
3484                              + a[ijl-lx+1]* s[mm-l+ix]) >> is;
3485          }
3486       }
3487    }
3488 
3489    i = ly - 1;                /* last lower right corner with wrap around */
3490    j = lx - 1;
3491    ij = lx*ly - 1;
3492    ijl = lx - 1;
3493    IJ = (i*ix+i1)*im_height + j*ix + i1;
3494    for (k=0; k < ix; k++) {
3495       IJk = IJ + k*im_height ;
3496       if ( IJk >= IM2 ) IJk -= IM2;
3497       kk = k0 - ((k * ix) << 1);
3498       mm = kk + dkk;
3499       for (l=0; l < ix; l++) {
3500          IJK = IJk;
3501          if ( (J + l) >= im_height ) IJK = IJk - im_height;
3502          tmp_imx[IJK+l]
3503            = imx[IJK+l] = ( a[ij]      * s[kk-l]
3504                           + a[ij-lx+1] * s[kk-l+ix]
3505                           + a[ijl]     * s[mm-l]
3506                           + a[ijl-lx+1]* s[mm-l+ix]) >> is;
3507       }
3508    }
3509 
3510    for (i=0; i < ly - 1; i++) {        /* the rest of the field */
3511       ii = i*lx;
3512       II = (i*ix+i1)*im_height + i1;
3513       for (j=0; j < lx - 1; j++) {
3514          ij  = ii+j;
3515          ijl = ij+lx;
3516          J   = j*ix;
3517          IJ  = II + J;
3518          for (k=0; k < ix; k++) {
3519             IJk = IJ + k*im_height ;
3520             kk = k0 - ((k * ix) << 1);
3521             mm = kk + dkk;
3522             for (l=0; l < ix; l++) {
3523                tmp_imx[IJk+l]
3524                  = imx[IJk+l] = ( a[ij]    * s[kk-l]
3525                                 + a[ij+1]  * s[kk-l+ix]
3526                                 + a[ijl]   * s[mm-l]
3527                                 + a[ijl+1] * s[mm-l+ix]) >> is;
3528             }
3529          }
3530       }
3531    }
3532 }
3533 
3534 /* ------------ */ /* Don't use before first Resample() and Load_Any_Arr(). */
3535    void            /* Load_Any_Arr() allocate memory for theImage. */
Put_image(n)3536    Put_image(n)    /* Put_image() needs THIS memory. */
3537    int n;
3538 /* ------------ */
3539 {
3540    register int    min2, max2, i, dd;
3541    register float  coef2, del2;
3542    int             xtemp1, xtemp2, ytemp1, ytemp2, xmat, ymat, xm, ym, xxx;
3543 
3544    if ( (n == old_im) && AJ_PseudoColor ) {
3545       for (i = 0; i < IM_ARR; i++) imx[i] = tmp_imx[i];
3546    }
3547 #ifdef USE_MCW
3548    else if ( n < 0 ){
3549       mcw_load() ;
3550       for( i=0 ; i < IM_ARR ; i++ ) tmp_ar[i] = mcw_im[i] ;
3551       SIZE_tmp_ar( im_height ) ;
3552       Resample(im_tmp_ar);
3553       strcpy(T_name,"Medical College of Wisconsin") ;
3554       strcpy(G_name,"Medical College of Wisconsin") ;
3555       strcpy(I_name,"MCW") ;
3556       Allow_new_name(Argc, Argv);
3557       old_im = -9999 ;
3558    }
3559 #endif
3560    else {
3561       nowim   = SAR(n) ;
3562       nowsize = SIZ(n) ;
3563       if( RWC_autoscale || (n >= npoints) ){   /* Autoscale these */
3564          min2 =  32767;
3565          max2 = -32768;
3566          for (i=0; i < nowsize; i++) {
3567             if ( nowim[i] < min2 ) min2 = nowim[i];
3568             if ( nowim[i] > max2 ) max2 = nowim[i];
3569          }
3570          del2 = max2 - min2;
3571          if (del2 < 1.) del2 = 1.;
3572          coef2 = ( (float) NC - 1.) / del2;
3573       }
3574       else {
3575          coef2 = coef1;
3576          min2 = min1;
3577       }
3578                              /* make differential single image */
3579       if ( (n<npoints) && (diff_im || avr_grp) ) {
3580          if ( ! avr_grp )
3581             for (i=0; i < ar_size; i++) tmp_ar[i] = nowim[i] - ref_ar[i];
3582 
3583                               /* make average image */
3584          else {
3585             Av_1 = n;
3586             Av_2 = Av_1 + Av_length - 1;
3587             for (i=0; i< ar_size; i++) av_ar[i] = 0;
3588             for (i=0; i < ar_size; i++) {
3589                for (j=Av_1; j <= Av_2; j++) av_ar[i] += SAR(j)[i];
3590             }
3591             for (i=0; i < ar_size; i++)  av_ar[i] /= Av_length;
3592 
3593                               /* average against ref image */
3594             if ( avr_grp && diff_im )
3595                for (i=0; i < ar_size; i++) tmp_ar[i] = av_ar[i] - ref_ar[i];
3596 
3597                               /* pure average image */
3598             else
3599                for (i=0; i < ar_size; i++) tmp_ar[i] = av_ar[i];
3600 
3601          }
3602                               /* renormalize image */
3603          min2 =  32767;
3604          max2 = -32768;
3605          for (i=0; i < ar_size; i++) {
3606             if ( tmp_ar[i] < min2 ) min2 = tmp_ar[i];
3607             if ( tmp_ar[i] > max2 ) max2 = tmp_ar[i];
3608          }
3609          del2 = max2 - min2;
3610          if (del2 < 1.)  del2 = 1.;
3611          coef2 = ( (float) NC - 1.) / del2;
3612          for (i=0; i < ar_size; i++)
3613             tmp_ar[i] = (int)((float)(tmp_ar[i]-min2)*coef2 + .5);
3614       }
3615       else if( LSQ_imedit[LSQ_code] != LSQ_EDIT_NONE ){
3616          int lsqnum , i,j ;
3617          float sum ;
3618 
3619          lsqnum = LSQ_refcount - LSQ_imedit[LSQ_code] ;
3620 
3621          min2 =  32767;
3622          max2 = -32768;
3623          for( i=0 ; i < nowsize ; i++ ){
3624             sum = nowim[i] ;
3625             for(j=0 ; j < lsqnum ; j++ )
3626                sum -= LSQ_ref[j]->ts[n] * LSQ_fit[j][i] ;
3627             tmp_ar[i] = sum ;
3628             if ( tmp_ar[i] < min2 ) min2 = tmp_ar[i];
3629             if ( tmp_ar[i] > max2 ) max2 = tmp_ar[i];
3630          }
3631          del2 = max2 - min2;
3632          if (del2 < 1.)  del2 = 1.;
3633          coef2 = ( (float) NC - 1.) / del2;
3634          for (i=0; i < ar_size; i++)
3635             tmp_ar[i] = (int)((float)(tmp_ar[i]-min2)*coef2 + .5);
3636       }
3637       else{                                       /* Normal Image */
3638          for (i=0; i < nowsize; i++)              /* renormalize data */
3639             tmp_ar[i] = (int)((float)(nowim[i]-min2)*coef2 + .5);
3640       }
3641 
3642       SIZE_tmp_ar( allim[n]->nx ) ;
3643 
3644       Resample(im_tmp_ar);
3645       top_nr_name(allim[n]->name) ;
3646       Allow_new_name(Argc, Argv);
3647       DrawTopWindow();
3648       old_im = n;
3649    }
3650 
3651    if( !RWC_framehide ){
3652 
3653       if ( x_mag == 1 ) dd = 0;   /* extra correction for 64 and 128 */
3654       else              dd = 1;
3655       xxx = max(0, x_mag/2 - 1);        /* stuff for proper pivot and frame */
3656       xm = x_mag - 1;
3657       ym = x_mag - 1;
3658       xmat = x_mag * (matx - 1) + x_mag/2 + 1;
3659       ymat = x_mag * (maty - 1) + x_mag/2 + 1;
3660 
3661       ytemp1 = x_mag * (ypoint + yc) + ym - dd;
3662       if (ytemp1 < 0)          ytemp1 += im_height;
3663       if (ytemp1 >= im_height) ytemp1 -= im_height;
3664 
3665       ytemp2 = x_mag * (ypoint + yc - maty + 1) - dd;
3666       if (ytemp2 < 0)          ytemp2 += im_height;
3667       if (ytemp2 >= im_height) ytemp2 -= im_height;
3668 
3669       for (i=0; i < xmat + xxx; i++) {
3670         xtemp1 = x_mag * (xpoint - xc) + i - dd;
3671         if (xtemp1 < 0)          xtemp1 += im_height;
3672         if (xtemp1 >= im_height) xtemp1 -= im_height;
3673 
3674         imx[ytemp1 * im_height + xtemp1] = fr_index;
3675         imx[ytemp2 * im_height + xtemp1] = fr_index;
3676       }
3677 
3678       xtemp1 = x_mag * (xpoint - xc) - dd;
3679       if (xtemp1 < 0)          xtemp1 += im_height;
3680       if (xtemp1 >= im_height) xtemp1 -= im_height;
3681 
3682       xtemp2 = x_mag * (xpoint - xc + matx - 1) + xm - dd;
3683       if (xtemp2 < 0)          xtemp2 += im_height;
3684       if (xtemp2 >= im_height) xtemp2 -= im_height;
3685 
3686       for (i=0; i < ymat; i++) {
3687          ytemp1 = x_mag * (ypoint + yc) - i + ym - dd;
3688          if (ytemp1 < 0)          ytemp1 += im_height;
3689          if (ytemp1 >= im_height) ytemp1 -= im_height;
3690 
3691          imx[ytemp1 * im_height + xtemp1] = fr_index;
3692          imx[ytemp1 * im_height + xtemp2] = fr_index;
3693       }
3694    } /* end if !RWC_framehide */
3695 
3696    if( RWC_do_overfim && !RWC_overhide ){
3697       short dont_overlay ;
3698       dont_overlay = fr_index ;
3699       RWC_short_overlay( im_height,im_height,imx , RWC_nxim,RWC_nyim ,
3700                          RWC_OVFLAG,dont_overlay, RWC_checker , RWC_imover ) ;
3701    }
3702 
3703    if ( !AJ_PseudoColor ) {
3704       Load_Next_Arr(theBelt, belt_arr, BELT_W, im_height);
3705       MResize(&expBelt,&eW,&eH,theBelt,eW,eH);
3706    }
3707    XPutImage(theDisp, theWindow, theGC, expBelt, 0, 0, eHIGH, 0, eW, eH);
3708 
3709    Load_Next_Arr(theImage, imx,im_height,im_height);
3710    MResize(&expImage,&eWIDE,&eHIGH,theImage,eWIDE,eHIGH);
3711    XPutImage(theDisp, theWindow, theGC, expImage,0, 0, 0, 0, eWIDE, eHIGH);
3712 }
3713 
3714 /* ---------------------------------- */   /* Create Image from the im_arr */
3715    void
Load_Next_Arr(Image,im_arr,x,y)3716    Load_Next_Arr(Image, im_arr, x, y)      /* Usage: Load_Next... */
3717    short int im_arr[];
3718    int       x, y;
3719    XImage    *Image;
3720 /* ---------------------------------- */
3721 {
3722 
3723    if ( AJ_PseudoColor ) Load_Next_ind(Image, im_arr, x, y);
3724    else                  Load_Next_RGB(Image, im_arr, x, y);
3725 }
3726 
3727 /* ---------------------------------- */
3728    void
Load_Next_RGB(Image,im_arr,x,y)3729    Load_Next_RGB(Image, im_arr, x, y)
3730    short int im_arr[];
3731    int       x, y;
3732    XImage    *Image;
3733 /* ---------------------------------- */   /* RGB version */
3734 {
3735    register int   i, k, last;
3736    byte      *a8, *i8, *m8;
3737    unsigned short *a16, *i16;
3738    unsigned int   *a32, *i32;
3739 
3740    last  = x * y;
3741 
3742    for (i=0; i < last; i++)
3743       if ( im_arr[i] < 0 ) im_arr[i] = STD_indx[-im_arr[i]-1];
3744 
3745    k = 0;
3746    switch( bperpix ) {
3747       case 32:
3748          a32 = (unsigned int  *) Image->data;
3749          i32 = (unsigned int  *) AJ_RGB;
3750          for (i=0; i < last; i++) {
3751             *a32++ =  i32[im_arr[k++]];
3752          }
3753       break ;
3754 
3755       case 24:
3756          a8 = (byte *) Image->data;
3757          i8 = (byte *) AJ_RGB;
3758          for (i=0; i < last; i++) {
3759             m8 =  i8 + im_arr[k++] * 3;
3760             *a8++ = *m8++;
3761             *a8++ = *m8++;
3762             *a8++ = *m8++;
3763          }
3764       break ;
3765 
3766       case 16:
3767          a16 = (unsigned short *) Image->data;
3768          i16 = (unsigned short *) AJ_RGB;
3769          for (i=0; i < last; i++) {
3770             *a16++ =  i16[im_arr[k++]];
3771          }
3772       break ;
3773 
3774       case 8:
3775          a8 = (byte *) Image->data;
3776          i8 = (byte *) AJ_RGB;
3777          for (i=0; i < last; i++) {
3778             *a8++ =  i8[im_arr[k++]];
3779          }
3780       break ;
3781    }
3782 }
3783 
3784 /* ---------------------------------- */   /* Create Image from the im_arr */
3785    void
Load_Next_ind(Image,im_arr,x,y)3786    Load_Next_ind(Image, im_arr, x, y)      /* Usage: Load_Next... */
3787    short int im_arr[];                     /* Uses own 16 colors for nega- */
3788    int       x, y;                         /* tive numbers (-1 - -16).     */
3789    XImage    *Image;
3790 /* ---------------------------------- */   /* 8 and 12 bit planes work OK. */
3791 {
3792   register char *ptr;
3793   register int   i, j, k, iN, iE;
3794   int        Width, Hight;
3795 
3796   iN = (Planes + 7)/8;             /* 1 or 2, pointer increment */
3797   iE = iN - 1;                     /* 0 or 1 for next pointer */
3798 
3799   Width = x;      /* Image width  */
3800   Hight = y;      /* Image higth  */
3801 
3802   ptr = Image->data;
3803   k = 0;
3804   for (i=0; i<Hight; i++)
3805      for (j=0; j<Width; j++, ptr += iN)
3806         if(im_arr[k] >= 0) {
3807           *ptr = pixels[im_arr[k]] >> 8;
3808           *(ptr + iE) = pixels[im_arr[k++]];
3809         }
3810         else {
3811           *ptr = STD_colors(-im_arr[k]) >> 8;
3812           *(ptr + iE) = STD_colors(-im_arr[k++]);
3813         }
3814 }
3815 
3816 /* ---------------------------- */
3817    void
Allow_new_name(argc,argv)3818    Allow_new_name(argc, argv)
3819    int  argc;
3820    char *argv[];
3821 /* ---------------------------- */
3822 {
3823    XSetStandardProperties(theDisp, theWindow, T_name, T_name, None,
3824                           argv, argc, NULL);
3825    XSetStandardProperties(theDisp, GWindow, G_name, I_name, None,
3826 			  argv, argc, NULL);
3827 }
3828 
3829 /* ----------------------------- */   /* plot scaled new_line to pixmap  */
plot_line()3830    void plot_line()
3831 /* ----------------------------- */
3832 {
3833    register int i,j, m, temp, index, ix, iy, xtemp, ytemp;
3834    int lsqnum , lsqfit , base , use_base , bb ;
3835    float f0;
3836 
3837    m = ar_size;
3838 
3839    lsqnum = 0 ;
3840    lsqfit = 0 ;
3841    if( RWC_do_overfim && RWC_ideal != NULL && LSQ_fitim != NULL ){
3842       switch( LSQ_code ){
3843          default:          lsqnum = 0                ; lsqfit = 0 ; break ;
3844          case LSQ_FITORT:  lsqnum = LSQ_refcount - 1 ; lsqfit = 1 ; break ;
3845          case LSQ_SUBORT:  lsqnum = LSQ_refcount - 1 ; lsqfit = 0 ; break ;
3846          case LSQ_FITALL:  lsqnum = LSQ_refcount     ; lsqfit = 1 ; break ;
3847          case LSQ_SUBALL:  lsqnum = LSQ_refcount     ; lsqfit = 0 ; break ;
3848          case LSQ_SORFID:  lsqnum = LSQ_refcount - 1 ; lsqfit = 2 ; break ;
3849       }
3850    }
3851 
3852    /** RWCox: 2 Aug 1996
3853               load data from images into "val" array here,
3854               instead of in main loop.  this allows loading of 'base' **/
3855 
3856    base = 40000 ;
3857    for (ix=0; ix < matx; ix++) {
3858       xtemp = xpoint + ix - xc;
3859       if (xtemp < 0)        xtemp += im_size;
3860       if (xtemp >= im_size) xtemp -= im_size;
3861       for (iy=0; iy < maty; iy++) {
3862          ytemp = ypoint - iy + yc;
3863          if (ytemp < 0)        ytemp += im_size;
3864          if (ytemp >= im_size) ytemp -= im_size;
3865          index = ytemp * im_size + xtemp;
3866          for (i=0; i < npoints; i++){
3867             val[ix][iy][i] = bb = SAR(i)[index] ;
3868             if( bb < base ) base = bb ;
3869          }
3870       }
3871    }
3872 
3873    use_base = (RWC_groupbase && lsqnum == 0) ;
3874 
3875    for (ix=0; ix < matx; ix++) {
3876       xtemp = xpoint + ix - xc;
3877       if (xtemp < 0)        xtemp += im_size;
3878       if (xtemp >= im_size) xtemp -= im_size;
3879       for (iy=0; iy < maty; iy++) {
3880          ytemp = ypoint - iy + yc;
3881          if (ytemp < 0)        ytemp += im_size;
3882          if (ytemp >= im_size) ytemp -= im_size;
3883          index = ytemp * im_size + xtemp;
3884 
3885          if( lsqnum > 0 ){
3886             float sum ;
3887             for( i=0 ; i < npoints ; i++ ){
3888                sum = 0.0 ;
3889                for(j=0 ; j < lsqnum ; j++ )
3890                   sum += LSQ_ref[j]->ts[i] * LSQ_fit[j][index] ;
3891 
3892                switch( lsqfit ){
3893                   /*fall*/
3894                   case 2: LSQ_val[i] = LSQ_ref[j]->ts[i] * LSQ_fit[j][index] ;
3895                   case 0: val[ix][iy][i] -= sum ;
3896                           break ;
3897                   case 1: LSQ_val[i]      = sum ;
3898                           break ;
3899                }
3900             }
3901 
3902          }
3903 
3904          /** scale data **/
3905 
3906          if( use_base ){
3907             if ( AJ_base ) pmin[ix][iy] = 0;
3908             else           pmin[ix][iy] = base ;
3909          } else {
3910             pmin[ix][iy] = 40000;
3911             for (i=0; i < npoints; i++)
3912                pmin[ix][iy] = min(pmin[ix][iy],val[ix][iy][i]);
3913          }
3914 
3915          if (iscale > 0) {
3916            for (i=0; i < npoints; i++)
3917               plot[ix][iy][i] = (val[ix][iy][i]-pmin[ix][iy])*iscale;
3918            pmax[ix][iy] = pmin[ix][iy] + gy / iscale;
3919          }
3920          else {
3921             temp = -iscale;
3922             for (i=0; i < npoints; i++)
3923                plot[ix][iy][i] = (val[ix][iy][i]-pmin[ix][iy])/temp;
3924             pmax[ix][iy] = pmin[ix][iy] + gy * temp;
3925          }
3926 
3927          /** plot scaled data **/
3928 
3929          line_color("black");
3930          if ( AJ_sigma > 0. ) {
3931             AJ_off = AJ_nr/2;
3932             for (i=0; i < AJ_off; i++) {
3933                f_plot[i] = 0.;
3934                f_plot[npoints+i] = 0.;
3935             }
3936             f_plot[npoints+AJ_nr+1] = 0.;
3937             for (i=0; i < npoints; i++)
3938                f_plot[AJ_off+i] = plot[ix][iy][i];
3939             for (m=0; m < npoints; m++) {
3940                f0 = 0.;
3941                for (i=0; i <= AJ_nr; i++) f0 += AJ_gauss[i] * f_plot[m+i];
3942                i_plot[m] = f0 * AJ_norm;
3943             }
3944             for (i=0; i < npoints; i++) {
3945                a_line[i].x = xorigin[ix][iy] + i*gx/(npoints-1);
3946                a_line[i].y = idY - yorigin[ix][iy] - i_plot[i];
3947             }
3948          }
3949          else {
3950             for (i=0; i < npoints; i++) {
3951                a_line[i].x = xorigin[ix][iy] + i*gx/(npoints-1);
3952                a_line[i].y = idY - yorigin[ix][iy] - plot[ix][iy][i];
3953             }
3954          }
3955          XDrawLines(theDisp, pxWind, theGC, a_line, npoints, CoordModeOrigin);
3956 
3957          /*** draw the LSQ_val fit to the data as well **/
3958 
3959          if( lsqnum > 0 && lsqfit ){
3960             float *id = RWC_ideal->ts ;
3961 
3962             if (iscale > 0) {
3963               for (i=0; i < npoints; i++)
3964                  LSQ_plot[i] = (LSQ_val[i]-pmin[ix][iy])*iscale;
3965             }
3966             else {
3967                temp = -iscale;
3968                for (i=0; i < npoints; i++)
3969                   LSQ_plot[i] = (LSQ_val[i]-pmin[ix][iy])/temp;
3970             }
3971             for (i=0; i < npoints; i++) {
3972                a_line[i].x = xorigin[ix][iy] + i*gx/(npoints-1);
3973                a_line[i].y = idY - yorigin[ix][iy] - LSQ_plot[i];
3974                if( (matx <= 3) && (maty <= 3) && fabs(id[i]) >= 33333.0 )
3975                   Cpointer_PIXWIN( a_line[i].x , a_line[i].y , "blue" ) ;
3976             }
3977             line_color("red3");
3978             XDrawLines(theDisp, pxWind, theGC, a_line, npoints, CoordModeOrigin);
3979          }
3980 
3981       } /* end loop iy */
3982       XFlush(theDisp);
3983    } /* end loop ix */
3984 
3985    /*** draw FIM ref function ***/
3986 
3987    if( RWC_do_overfim             &&
3988        RWC_ideal != NULL          &&
3989        RWC_ideal->len >= npoints  &&
3990        kFI3_show_ref > 0             ){
3991 
3992       float idmax , idmin , val , yscal,yoff ;
3993       float *id = RWC_ideal->ts ;
3994       int ii , xg,yg , xbot,ybot,xtop,ytop ;
3995       XPoint one_line[2] ;
3996 
3997 #define REFTS_FRAC 0.369  /* fraction of one graph that this takes up */
3998 
3999       idmax = -99999.0 ;
4000       idmin =  99999.0 ;
4001 
4002       /*** find scale factor for plot ***/
4003 
4004       for( ii=0 ; ii < npoints ; ii++ ){
4005          val = id[ii] ;
4006          if( fabs(val) < 33333.0 ){
4007             idmax = MAX(idmax,val) ;
4008             idmin = MIN(idmin,val) ;
4009          }
4010       }
4011       if( idmax >= 33333.0 || idmax <= -33333.0 || idmax <= idmin ) return ;
4012 
4013       yscal = REFTS_FRAC * gy / (idmax-idmin) ;
4014       yoff  = (0.97-REFTS_FRAC) * gy ;
4015 
4016       /*** scale into a_line (with no origins yet) ***/
4017 
4018       for (i=0; i < npoints; i++) {
4019          a_line[i].x = i*gx/(npoints-1);
4020          val = ( fabs(id[i]) < 33333.0 ) ? (id[i]) : (idmin) ;
4021          a_line[i].y = idY - (yoff+yscal*(val-idmin));
4022       }
4023 
4024       /*** for each line, for each plot, put into pixmap ***/
4025 
4026       line_color("red") ;
4027 
4028       for (i=0; i < npoints-1 ; i++) {
4029          if( fabs(id[i]) < 33333.0 && fabs(id[i+1]) < 33333.0 ){
4030             line_color("red") ;   /* red for "good" lines */
4031          } else {
4032             line_color("blue") ;  /* blue for "bad" lines */
4033          }
4034 
4035         /*** draw into every plot in matrix ***/
4036 
4037         if( kFI3_show_ref == 1 ){
4038            xbot = xc ; xtop = xbot+1 ;  /* just do center plot */
4039            ybot = yc ; ytop = ybot+1 ;
4040         } else {
4041            xbot = ybot = 0 ;            /* do all plots */
4042            xtop = matx;
4043            ytop = maty;
4044         }
4045 
4046         for( yg=ybot ; yg < ytop ; yg++ ){
4047            for( xg=xbot ; xg < xtop ; xg++ ){
4048               one_line[0].x = a_line[i].x   + xorigin[xg][yg] ;
4049               one_line[1].x = a_line[i+1].x + xorigin[xg][yg] ;
4050               one_line[0].y = a_line[i].y   - yorigin[xg][yg] ;
4051               one_line[1].y = a_line[i+1].y - yorigin[xg][yg] ;
4052               XDrawLines(theDisp, pxWind, theGC, one_line, 2, CoordModeOrigin);
4053               if( (matx <= 3) && (maty <=3) &&
4054                   kFI3_show_ref == 1 && fabs(id[i]) >= 33333.0 )
4055                  Cpointer_PIXWIN( one_line[0].x , one_line[0].y , "blue" ) ;
4056            }
4057         }  /* end of loops over boxes */
4058       } /* end of loop over points in plot */
4059 
4060    } /* end of FIM stuff */
4061 
4062 }
4063 
4064 /* ----------------------------- */ /* draw marker for current image  */
draw_marker()4065    void draw_marker()
4066 /* ----------------------------- */ /* marker fixed (shifted by one im) AJJ */
4067 {
4068    register int i, j, k, xo, yo, x1, dx;
4069    register float g, f0;
4070 
4071    if (mark) {
4072      line_color(color[color_index]);
4073      g = grid_coef * grid_far[grid_index + FT_grid];
4074      for (i=0; i < matx; i++) {
4075         for (j=1;j<=npoints/g;j++) {
4076            f0 = ((float) j * g - 1.) * (float) gx / (float) (npoints - 1);
4077            k = xorigin[i][0] + (int) f0;
4078            plotx(k,mdy1, 0);
4079            plotx(k,mdy1+maty*gy, 1);
4080         }
4081      }
4082    }
4083 
4084 #ifdef FILL_WITH_CYAN
4085    line_color("cyan");
4086    xo = xorigin[xc][yc];
4087    yo = idY - yorigin[xc][yc] - gy;
4088    XFillRectangle(theDisp, pxWind, theGC, xo, yo, gx, gy);
4089 #else
4090    xo = xorigin[xc][yc] ; yo = yorigin[xc][yc] ;
4091    g  = 5 ;
4092    for( j=1 ; j <= g ; j++ ){
4093       plotx( xo+j    , yo+j    , 0 ) ;
4094       plotx( xo+j    , yo+gy-j , 1 ) ;
4095       plotx( xo+gx-j , yo+gy-j , 1 ) ;
4096       plotx( xo+gx-j , yo+j    , 1 ) ;
4097       plotx( xo+j    , yo+j    , 1 ) ;
4098    }
4099 #endif
4100 
4101    xo = xorigin[xc][yc];
4102    yo = idY - yorigin[xc][yc] - gy;
4103 
4104    if (diff_im) {
4105       line_color("blue");
4106       x1 = Im_1*gx/(npoints-1);
4107       dx = (Im_2 - Im_1)*gx/(npoints-1) + 1;
4108       XFillRectangle(theDisp, pxWind, theGC, xo + x1, yo, dx, gy);
4109    }
4110 
4111    if (avr_grp) {
4112       line_color("red");
4113       x1 = Av_1*gx/(npoints-1);
4114       dx = (Av_2 - Av_1)*gx/(npoints-1) + 1;
4115       XFillRectangle(theDisp, pxWind, theGC, xo + x1, yo, dx, gy);
4116    }
4117 
4118    if (mark) {
4119 #ifdef FILL_WITH_CYAN
4120      line_color("white");
4121 #else
4122      line_color(color[color_index]);
4123 #endif
4124      g = grid_coef * grid_far[grid_index + FT_grid];
4125      for (j=1;j<=npoints/g;j++) {
4126         f0 = ((float) j * g - 1.) * (float) gx / (float) (npoints - 1);
4127         k = xorigin[xc][yc] + (int) f0;
4128         plotx(k,yorigin[xc][yc]   , 0);
4129         plotx(k,yorigin[xc][yc]+gy, 1);
4130      }
4131    }
4132 }
4133 
4134 /* ----------------------------- */   /* scale plot up and redraw  */
scale_up()4135    void scale_up()
4136 /* ----------------------------- */
4137 {
4138    if (iscale > 0) iscale *= 2;
4139    else if (iscale < -2) iscale /= 2;
4140    else iscale = 1;
4141 }
4142 
4143 /* ----------------------------- */   /* scale plot up and redraw  */
scale_down()4144    void scale_down()
4145 /* ----------------------------- */
4146 {
4147    if (iscale > 1) iscale /= 2;
4148    else if (iscale < 0) iscale *= 2;
4149    else iscale = -2;
4150 }
4151 
4152 /* ----------------------------- */   /* decrease matrix and redraw  */
mat_down(n)4153    void mat_down(n)
4154    int n;
4155 /* ----------------------------- */
4156 {
4157    matx_0 = matx;
4158    maty_0 = maty;
4159    if ( n == 0 ) {
4160       matx--;
4161       if      (matx < 1)       matx = 1;
4162       else if (matx > MAT_MAX) matx = MAT_MAX;
4163    }
4164    maty--;
4165    if      (maty < 1)       maty = 1;
4166    else if (maty > MAT_MAX) maty = MAT_MAX;
4167    if ( (matx != matx_0) || (maty != maty_0) ) {
4168       init_mat();
4169       RWC_framehide = 0 ;
4170       Put_image(Im_Nr);
4171       redraw_graph();
4172       DrawSubWindow();
4173    }
4174 }
4175 
4176 /* ----------------------------- */   /* increase matrix and redraw  */
mat_up(n)4177    void mat_up(n)
4178    int n;
4179 /* ----------------------------- */
4180 {
4181    matx_0 = matx;
4182    maty_0 = maty;
4183    if ( n == 0 ) {
4184       matx++;
4185       if      (matx < 1)       matx = 1;
4186       else if (matx > MAT_MAX) matx = MAT_MAX;
4187    }
4188    maty++;
4189    if      (maty < 1)       maty = 1;
4190    else if (maty > MAT_MAX) maty = MAT_MAX;
4191 
4192    if ( (matx != matx_0) || (maty != maty_0) ) {
4193       init_mat();
4194       RWC_framehide = 0 ;
4195       Put_image(Im_Nr);
4196       redraw_graph();
4197       DrawSubWindow();
4198    }
4199 }
4200 
4201 /* ----------------------------- */   /* initialize matrix stuff  */
init_mat()4202    void init_mat()
4203 /* ----------------------------- */
4204 {
4205    int i, j;
4206 
4207    gx = gx_max / matx;
4208    gy = gy_max / maty;
4209    if (gx < 1) { gx = 1; gx_max = matx; }
4210    if (gy < 1) { gy = 1; gy_max = maty; }
4211    for (i=0; i < matx; i++) {
4212       for (j=0; j < maty; j++) {
4213          xorigin[i][j] = mdx1 + i * gx;
4214          yorigin[i][j] = mdy1 + j * gy;
4215       }
4216    }
4217    xc = matx/2;
4218    yc = (maty-1)/2;
4219 }
4220 
4221 /* ----------- */
4222    void
init_grid()4223    init_grid()
4224 /* ----------- */
4225 {
4226    grid_far[GRID_NUM]   = grid_far[0] = 2;
4227    grid_far[GRID_NUM+1] = grid_far[1] = 5.;
4228    grid_far[GRID_NUM+2] = grid_far[2] = 10.;
4229    grid_far[GRID_NUM+3] = grid_far[3] = 20.;
4230    grid_far[GRID_NUM+4] = grid_far[4] = 50.;
4231    grid_far[GRID_NUM+5] = grid_far[5] = 100.;
4232    grid_far[GRID_NUM+6] = grid_far[6] = 200.;
4233    grid_far[GRID_NUM+7] = grid_far[7] = 500.;
4234    grid_index = 3;
4235 }
4236 
4237 /* ----------------------------- */   /* decrease grid spacing and redraw  */
grid_down()4238    void grid_down()
4239 /* ----------------------------- */
4240 {
4241    int old;
4242 
4243    old = grid_index;
4244    grid_index--;
4245    if (grid_index < 0) grid_index = 0;
4246    if (grid_index!= old) {
4247       redraw_graph();
4248       DrawSubWindow();
4249    }
4250 }
4251 
4252 /* ----------------------------- */   /* increase grid spacing and redraw  */
grid_up()4253    void grid_up()
4254 /* ----------------------------- */
4255 {
4256    int old;
4257 
4258    old = grid_index;
4259    grid_index++;
4260    if (grid_index >= GRID_NUM) grid_index = GRID_NUM - 1;
4261    if (grid_index!= old) {
4262       redraw_graph();
4263       DrawSubWindow();
4264    }
4265 }
4266 
4267 /* ------------ */
4268    void
init_const()4269    init_const()
4270 /* ------------ */
4271 {
4272    iscale = 4;
4273    auto_scale = .4;
4274 
4275    xpoint = im_size/2;
4276    ypoint = im_size/2;
4277 
4278    xspace = 5;
4279    yspace = 20;
4280    mytxt = 20;
4281    mdx1   = GL_DLX + 1;
4282    mdy1   = GB_DLY + 1;
4283    idX   = GL_DLX + gx_max + GR_DLX;
4284    idY   = GB_DLY + gy_max + GT_DLY;
4285    mark = 1;
4286    color_index = 0;
4287    matx = 3;
4288    maty = 3;
4289    init_mat();
4290 }
4291 
4292 /* ------------------------------  resize graph window */
redo_graph_window(xs,ys)4293    void redo_graph_window(xs, ys)
4294    int xs, ys;
4295 /* ------------------------------ */
4296 {
4297    idX = xs;   idY = ys;
4298    gx_max = idX - GL_DLX - GR_DLX;
4299    gy_max = idY - GB_DLY - GT_DLY;
4300    XFreePixmap(theDisp, pxWind) ;
4301    pxWind = XCreatePixmap(theDisp, GWindow, idX, idY, Planes);
4302    XMoveResizeWindow(theDisp, subWindow, 0, gy_max + GT_DLY, idX, GB_DLY);
4303    XMoveResizeWindow(theDisp, topWindow, 0, 0, idX, GT_DLY - 2);
4304    init_mat();
4305    redraw_graph();
4306 }
4307 
4308 /* ------------------------------------------------- Main link from main() C */
window_plane()4309    void window_plane()
4310 /* --------------------------------------------------- */
4311 {
4312    int  i, out_loop = 0, tmpx;
4313 
4314    XGCValues   gcv;
4315 
4316     CreateGraphWindow(NULL, 0);      /* Set theWindow properties */
4317 /* subWindow, topWindow and keys stuff is here ------- vvvvvvv ------- AJ*/
4318 
4319     ffc = XGetDefault(theDisp, Xdef_Name, "FKeyFore");
4320     fbc = XGetDefault(theDisp, Xdef_Name, "FKeyBack");
4321 
4322     /* Set normal default colors */
4323     ForeColor = BlackPixel(theDisp, theScreen);
4324     BackColor = WhitePixel(theDisp, theScreen);
4325 
4326     FKeyFore =  ForeColor;
4327     FKeyBack =  BackColor;
4328 
4329     if ( (ffc != NULL) && XAllocNamedColor(theDisp, CMap, ffc, &xcsd, &xced));
4330     else if (XAllocNamedColor(theDisp, CMap, "blue", &xcsd, &xced));
4331     else    FatalError ("XAllocNamedColor problem. AJ");
4332     FKeyFore=xcsd.pixel;
4333 
4334     if ( (fbc != NULL) && XAllocNamedColor(theDisp, CMap, fbc, &xcsd, &xced));
4335     else if (XAllocNamedColor(theDisp, CMap, "cyan", &xcsd, &xced));
4336     else    FatalError ("XAllocNamedColor problem. AJ");
4337     FKeyBack=xcsd.pixel;
4338 
4339    /** load key font from one of the candidate list **/
4340 
4341    tfont = XGetDefault(theDisp, Xdef_Name , "KeyFont");
4342    if( tfont != NULL ) tfont_hopefuls[0] = tfont ;
4343    else                tfont_hopefuls[0] = KFONT ;
4344    { int ifont ;
4345      for( ifont=0 ; tfont_hopefuls[ifont] != NULL ; ifont++ ){
4346         kfontinfo = XLoadQueryFont(theDisp, tfont_hopefuls[ifont]) ;
4347         if( kfontinfo != NULL ) break ;
4348      }
4349      if( kfontinfo == NULL ){
4350          FatalError("Can't open any text font!\n") ;
4351      }
4352      kfont = tfont_hopefuls[ifont] ;
4353    }
4354     keyfont = kfontinfo->fid;
4355 
4356     minwide = XTextWidth(kfontinfo, "MMMM", 4);
4357     keyhigh = kfontinfo->ascent + 7;
4358     for (i=0; i<N_KEYS; i++) {
4359        tmpx = XTextWidth(kfontinfo, xtkeys[i].st, strlen(xtkeys[i].st));
4360        keywide[i] = max(minwide, tmpx) + 2;
4361     }
4362 
4363     gcv.foreground = FKeyFore;
4364     gcv.function = GXcopy;
4365     gcv.font = keyfont;
4366     Fkeygc = XCreateGC(theDisp, GWindow, GCForeground|GCFunction|GCFont, &gcv);
4367 
4368     gcv.function = GXinvert;
4369     gcv.plane_mask = FKeyFore ^ FKeyBack;
4370     Fkeyigc = XCreateGC(theDisp, GWindow, GCFunction|GCPlaneMask, &gcv);
4371 
4372     Setup_subWindow();
4373 
4374     Setup_topWindow();
4375 
4376     Setup_keys();
4377 
4378 /* SUbWindow, topWindow and keys stuff is here ------- ^^^^^^^ ------- AJ*/
4379 
4380                          /* Make dummy window for text and graphic entry */
4381 
4382    pxWind = XCreatePixmap(theDisp, GWindow, idX, idY, Planes);
4383 
4384    New_Cursor(theDisp, GWindow, XC_left_ptr, "blue", "yellow"); /* cursor */
4385 
4386    /* Text color and font */
4387 
4388    XSelectInput(theDisp, GWindow, ExposureMask | KeyPressMask
4389                  | ButtonPressMask | StructureNotifyMask);
4390    XMapWindow(theDisp,GWindow);		/* Show window first time */
4391    XMapSubwindows(theDisp, GWindow);    /* All keys stuff */
4392 
4393 
4394    for (i = 0; i < N_KEYS+2; i++) exp_done[i] = 0;
4395 
4396    while (1) {
4397       Window wind;
4398 
4399       XNextEvent(theDisp, &first_event);
4400                                           /* Wait for window on */
4401       switch (first_event.type) {
4402          case Expose: {
4403             XExposeEvent *exp_event = (XExposeEvent *) &first_event;
4404             wind = exp_event->window;
4405 
4406             if (wind ==   GWindow)
4407                exp_done[N_KEYS] = 1;
4408             else if (wind == subWindow) {
4409                DrawSubWindow();
4410                exp_done[N_KEYS+1] = 1;
4411             }
4412             else if (wind == topWindow) {
4413                DrawTopWindow();
4414                exp_done[N_KEYS+2] = 1;
4415             }
4416             else {
4417                for (i=0; i < N_KEYS; i++) {
4418                   if (wind == key[i].wid) {
4419                      DrawKey(i);
4420                      exp_done[i] = 1;
4421                   }
4422                }
4423             }
4424             out_loop = exp_done[N_KEYS] * exp_done[N_KEYS+1]
4425                                         * exp_done[N_KEYS+2];
4426             for (i = 0; i < N_KEYS; i++)  out_loop *= exp_done[i];
4427             if (out_loop){
4428                return;
4429             }
4430             Allow_smaller_gr(Argc, Argv);
4431          }
4432          break;
4433 
4434          default:                /* ignore unexpected events */
4435          break;
4436       }
4437    }
4438 }
4439 
4440 /* ----------------- */
4441    void
Setup_subWindow()4442    Setup_subWindow()
4443 /* ----------------- */
4444 {
4445    unsigned long white; // long is OK here AJJ
4446 
4447    if (!(XAllocNamedColor(theDisp, CMap, "white", &any_col, &rgb_col)))
4448    FatalError ("XAllocNamedColor problem. AJ in Setup_subWindow()");
4449    white = any_col.pixel;
4450 
4451    sub_W_x = idX;
4452    sub_W_y = GB_DLY;
4453    subWindow = XCreateSimpleWindow(theDisp, GWindow, 0, gy_max + GT_DLY,
4454                      sub_W_x, sub_W_y, 1, white, white);
4455    XSelectInput(theDisp, subWindow, ExposureMask | ButtonPressMask |
4456                   ButtonReleaseMask);
4457 }
4458 
4459 /* --------------- */ /* Draw subWindow containing text info */
4460    void
DrawSubWindow()4461    DrawSubWindow()
4462 /* --------------- */
4463 {
4464    float   diff_prcnt, f0, f1, f2;
4465    int     str_x = 5, x, y, loc, i;
4466 
4467    line_color("white");
4468    XFillRectangle(theDisp, subWindow, theGC, 0, 0, idX, GB_DLY);
4469 
4470    sprintf (strp,"Im. rot.");
4471    subW_TXT(str_x, 35, strp);
4472    sprintf (strp,"clockwise");
4473    subW_TXT(str_x, 20, strp);
4474    sprintf(strp, "%d*90 deg.", rot_nr);
4475    subW_TXT(str_x,  5, strp);
4476    str_x += XTextWidth(mfinfo ,"clockwise", strlen("clockwise")) + 30;
4477 
4478    sprintf (strp,"X: %d", xpoint);
4479    subW_TXT(str_x, 28, strp);
4480    sprintf (strp,"Y: %d", ypoint);
4481    subW_TXT(str_x, 13, strp);
4482    str_x += XTextWidth(mfinfo, "X: 000", strlen("X: 000")) + 20;
4483 
4484    if( SIZ(Im_Nr) == ar_size ){
4485       int cenval = SAR(Im_Nr)[ypoint*im_size + xpoint] ;
4486 
4487       if ( grid_timed && (FT_grid == GRID_NUM) ) {
4488          f0 = (float) (Im_Nr+1) / grid_far[FT_grid];
4489          sprintf (strp,"Pix. value:%6d at im #%d  %5.2f Hz",
4490                         cenval, Im_Nr+1, f0);
4491       }
4492       else
4493          sprintf (strp,"Pix. value: %d at im #%d", cenval, Im_Nr+1);
4494       subW_TXT(str_x, 20, strp);
4495       loc = str_x;
4496 
4497       if ( grid_timed && (FT_grid == GRID_NUM) ) {
4498          f0 = grid_coef * grid_far[grid_index + FT_grid] / grid_far[FT_grid];
4499          sprintf (strp,"Grid:%5.2f Hz", f0);
4500       }
4501       else
4502          sprintf (strp,"Grid:%g", grid_coef * grid_far[grid_index + FT_grid]);
4503       subW_TXT(str_x, 35, strp);
4504 
4505       str_x += XTextWidth(mfinfo, "Grid:00000f Hz",
4506                            strlen("Grid:00000f Hz")) + 20;
4507       sprintf(strp, "Num: %d", npoints);
4508       subW_TXT(str_x, 35, strp);
4509 
4510       if ( AJ_sigma > 0. ) {
4511          sprintf(strp, "Sig: %g", AJ_sigma);
4512          subW_TXT(GL_DLX + 440, 5, strp);
4513       }
4514 
4515       if( Im_Nr < npoints ){
4516          i = ypoint*im_size + xpoint;
4517          if ( diff_im) {
4518             if ( avr_grp ) {
4519                diff_prcnt = (float) (200 * (av_ar[i] - ref_ar[i]))
4520                                  / (float) (av_ar[i] + ref_ar[i]);
4521             }
4522             else {
4523                diff_prcnt = (float) (200 * (val[xc][yc][Im_Nr] - ref_ar[i]))
4524                                  / (float) (val[xc][yc][Im_Nr] + ref_ar[i]);
4525             }
4526             sprintf(strp, "Deviation from ref base: %.2f%%", diff_prcnt);
4527             txt_color("red");
4528             subW_TXT(loc, 5, strp);
4529             txt_color("black");
4530 
4531          } else if( avr_grp ){  /** RWCox: 4 March 1996 **/
4532 
4533             sprintf(strp, "Averaged pixel: %d",
4534                     av_ar[ypoint*im_size + xpoint] ) ;
4535 
4536             if( (matx > 1) || (maty > 1) ){  /** RWCox: 2 Aug 1996 **/
4537                int ix,iy , xtemp,ytemp , index ;
4538                float sum = 0.0 ;
4539                for( ix=0 ; ix < matx; ix++ ){
4540                   xtemp = xpoint + ix - xc;
4541                   if (xtemp < 0)        xtemp += im_size;
4542                   if (xtemp >= im_size) xtemp -= im_size;
4543                   for( iy=0 ; iy < maty; iy++ ){
4544                      ytemp = ypoint - iy + yc;
4545                      if (ytemp < 0)        ytemp += im_size;
4546                      if (ytemp >= im_size) ytemp -= im_size;
4547                      index = ytemp * im_size + xtemp;
4548                      sum  += av_ar[index] ;
4549                   }
4550                }
4551                sum /= (matx*maty) ;
4552                ix   = strlen(strp) ;
4553                sprintf(strp+ix , " [%.1f]" , sum ) ;
4554             }
4555 
4556             txt_color("red");
4557             subW_TXT(loc, 5, strp);
4558             txt_color("black");
4559          } /* end of pure average */
4560          else {
4561             int i, ix, iy;
4562             f1 = f0 = 0.;
4563             if ( Time_avr ) {
4564                for (i=0; i < npoints; i++) f0 += val[xc][yc][i];
4565                f2 = (float) max(npoints, 1);
4566                f0 = f0 / f2;
4567                for (i=0; i < npoints; i++) {
4568                   f2 = (float) val[xc][yc][i] - f0;
4569                   f1 += f2 * f2;
4570                }
4571                f2 = (float) max(npoints, 1);
4572                f1 = f1 / f2;
4573                f1 = sqrt(f1);
4574                sprintf(strp, "Time avr: %.1f, Std dev: %.1f", f0, f1);
4575                txt_color("blue");
4576                subW_TXT(loc, 5, strp);
4577                txt_color("black");
4578             }
4579             else {
4580                for (ix=0;ix<matx;ix++) {
4581                   for (iy=0;iy<maty;iy++) {
4582                      f0 += val[ix][iy][Im_Nr];
4583                   }
4584                }
4585                f0 = f0 / (float) (matx*maty);
4586                for (ix=0;ix<matx;ix++) {
4587                   for (iy=0;iy<maty;iy++) {
4588                      f2 = (float) val[ix][iy][Im_Nr] - f0;
4589                      f1 += f2 * f2;
4590                   }
4591                }
4592                f1 = f1 / (float) (matx*maty);
4593                f1 = sqrt(f1);
4594                sprintf(strp, "Box avr: %.1f, Std dev: %.1f", f0, f1);
4595                txt_color("blue");
4596                subW_TXT(loc, 5, strp);
4597                txt_color("black");
4598             }
4599          }
4600 
4601          x = xorigin[xc][yc] + Im_Nr*gx/(npoints-1);
4602          y = idY - yorigin[xc][yc] - plot[xc][yc][Im_Nr];
4603          v_point_x = x;
4604          Vpointer(x, 0);
4605          Cpointer(x, y );
4606 
4607       }  /* end if */
4608    }  /* end if */
4609    return ;
4610 }
4611 
4612 /* ----------------- */
4613    void
Setup_topWindow()4614    Setup_topWindow()
4615 /* ----------------- */
4616 {
4617    unsigned long white; // long is OK here AJJ
4618 
4619    if (!(XAllocNamedColor(theDisp, CMap, "white", &any_col, &rgb_col)))
4620    FatalError ("XAllocNamedColor problem. AJ in Setup_topWindow()");
4621    white = any_col.pixel;
4622 
4623    top_W_x = idX;
4624    top_W_y = GT_DLY - 2;
4625    topWindow = XCreateSimpleWindow(theDisp, GWindow, 0, 0,
4626                      top_W_x, top_W_y, 1, white, white);
4627    XSelectInput(theDisp, topWindow, ExposureMask);
4628 }
4629 
4630 /* --------------- */ /* Draw topWindow with text info */
4631    void
DrawTopWindow()4632    DrawTopWindow()
4633 /* --------------- */
4634 {
4635    int  strwide , xmin , xleft ;
4636    char *str = "Differential Image";
4637    char str_fim[128] ;
4638 
4639    line_color("white");
4640    XFillRectangle(theDisp, topWindow, theGC, 0, 0, idX, top_W_y);
4641 
4642    txt_color("black");
4643    XDrawString(theDisp, topWindow, txtGC, 12,
4644                top_W_y - 5, T_name, strlen(T_name));
4645 
4646    xmin = 3 + 12 + XTextWidth(mfinfo,T_name,strlen(T_name)) ;
4647 
4648    if ( diff_im ) {
4649       txt_color("red");
4650       strwide = XTextWidth(mfinfo,str,strlen(str));
4651       xleft   = GL_DLX + (gx_max-strwide)/2 ;
4652       xleft   = MAX(xmin,xleft) ;
4653       XDrawString(theDisp, topWindow, txtGC,
4654                   xleft , top_W_y - 5, str, strlen(str));
4655       txt_color("black");
4656    } else if( RWC_do_overfim && RWC_ideal != NULL ){
4657 
4658       sprintf( str_fim , "%s %s:ref=%s thresh=%5.3f #ort=%d #pol=%d",
4659                LSQ_fimcode[LSQ_code] , DFILT_fimcode[DFILT_code] ,
4660                RWC_ideal->fname , RWC_pcthresh , RWC_numort,RWC_polort ) ;
4661 
4662       if( FIM_pressed ) txt_color("blue") ;
4663       else              txt_color("red");
4664 
4665       if( FFT_pressed ) txt_color("blue") ;
4666       else              txt_color("red");
4667 
4668       strwide = XTextWidth(mfinfo,str_fim,strlen(str_fim));
4669       xleft   = GL_DLX + (gx_max-strwide)/2 ;
4670       xleft   = MAX(xmin,xleft) ;
4671       XDrawString(theDisp, topWindow, txtGC,
4672                   xleft , top_W_y - 5, str_fim, strlen(str_fim) );
4673       txt_color("black");
4674    }
4675 }
4676 
4677 /* ------------ */
4678    void
Setup_keys()4679    Setup_keys()
4680 /* ------------ */
4681 {
4682    int i;
4683 
4684    key = &xtkeys[0];
4685 
4686    for (i=0; i < N_KEYS; i++) {
4687        key[i].x = PADDINGW;
4688        key[i].y = KEY_1_Y + i*(keyhigh + PADDINGH);
4689        key[i].width = keywide[i];
4690        key[i].height = keyhigh;
4691 
4692        key[i].fore=FKeyFore;
4693        key[i].back=FKeyBack;
4694 
4695        key[i].wid=XCreateSimpleWindow(theDisp, GWindow, key[i].x, key[i].y,
4696                                       key[i].width, key[i].height, 1,
4697                                       key[i].fore, key[i].back);
4698        New_Cursor(theDisp,  key[i].wid, XC_left_ptr, "yellow", "red");
4699        XSelectInput(theDisp, key[i].wid, ExposureMask | ButtonPressMask |
4700                   ButtonReleaseMask | EnterWindowMask | LeaveWindowMask);
4701    }
4702 }
4703 
4704 /* --------------- */
4705    void
DrawKey(keynum)4706    DrawKey(keynum)
4707    int keynum;
4708 /* --------------- */
4709 {
4710    char        *str;
4711    int         strwide;
4712    struct _key *kp;
4713    GC          AJkeygc; /* AJ new for proper color of the text */
4714 
4715    if( keynum < 0 || keynum >= N_KEYS ) return;
4716 
4717    kp = &key[keynum];
4718    str = kp->st;
4719    strwide = XTextWidth(kfontinfo,str,strlen(str));
4720 
4721    AJkeygc=Fkeygc;
4722 
4723    XClearWindow(theDisp,kp->wid) ;
4724 
4725    XDrawString(theDisp ,kp->wid, AJkeygc, (kp->width-strwide)/2,
4726                1 + kfontinfo->ascent, str, strlen(str));
4727 }
4728 
4729 /* ----------------- */
4730    void
InvertKey(keynum)4731    InvertKey(keynum)
4732    int keynum;
4733 /* ----------------- */
4734 {
4735    struct _key *kp;
4736    GC           AJkeyigc;
4737 
4738    if( keynum < 0 || keynum >= N_KEYS ) return;
4739 
4740    AJkeyigc = Fkeyigc;
4741    kp = &key[keynum];
4742 
4743    XFillRectangle(theDisp, kp->wid, AJkeyigc, 0, 0, kp->width, kp->height);
4744 }
4745 
4746 /* ---------------- */
4747    void
LetGoKey(keynum)4748    LetGoKey(keynum)
4749    int keynum;
4750 /* ---------------- */
4751 {
4752    if( keynum < 0 || keynum >= N_KEYS ) return;
4753    InvertKey(keynum);
4754    (*(key[keynum].fun))(keynum);
4755 }
4756 
4757 /* ------------- */
4758    int
Ims_rot(ikey)4759    Ims_rot(ikey)
4760    int ikey;
4761 /* ------------- */
4762 {
4763    register int i, j, k, l, m, n, s;
4764 
4765    old_im = -1;            /* to avoid faster reload of not rotated image */
4766 
4767    if( rot_direct == 0 ){            /* change key label */
4768       kROT_doall = ! kROT_doall ;
4769       xtkeys[kROT].st = (kROT_doall) ? (key_kROT_all) : (key_kROT_one) ;
4770       DrawKey(kROT) ;
4771       return 0;
4772    }
4773 
4774    if( rot_direct == 1 || rot_direct == -1 ){
4775       RWC_do_overfim = 0 ;
4776       if( RWC_imover != NULL ) { free(RWC_imover) ; RWC_imover = NULL ; }
4777       RWC_framehide = 0 ;
4778    } else {
4779       fprintf(stderr,"\n*** illegal rot_direct in Ims_rot() ***\n") ;
4780       XBell(theDisp,100) ;
4781       return 0;
4782    }
4783 
4784    if ( rot_direct == 1 ) {                         /* clockwise rotation */
4785       nowim = SAR(Im_Nr) ; k = DIM(Im_Nr) ; l = k-1 ; s = SIZ(Im_Nr) ;
4786       for (i=0; i < k; i++) {          /* rotate and redisplay actual one */
4787          m = i * k;
4788          for (j=0; j < k; j++)
4789             a_rot[m+j] = nowim[(l-j)*k+i];
4790       }
4791       for (i=0; i < s; i++) nowim[i] = a_rot[i];
4792 
4793       if( ! kROT_doall ){
4794          Put_image(Im_Nr ) ;
4795          return 0;
4796       }
4797 
4798       if ( diff_im && Im_Nr < npoints ) { /* rotate reference array too */
4799          for (i=0; i < k; i++) {
4800             m = i * k;
4801             for (j=0; j < k; j++)
4802                a_rot[m+j] = ref_ar[(l-j)*k+i];
4803          }
4804          for (i=0; i < s; i++) ref_ar[i] = a_rot[i];
4805       }
4806       if ( !avr_grp ) Put_image(Im_Nr);         /* put single image here */
4807                                                      /* rotate other data */
4808       for (n=0; n < N_im; n++) {
4809          nowim = SAR(n) ; k = DIM(n) ; l = k-1 ; s = SIZ(n) ;
4810          if ( n != Im_Nr ) {
4811             for (i=0; i < k; i++) {
4812                m = i * k;
4813                for (j=0; j < k; j++)
4814                   a_rot[m+j] = nowim[(l-j)*k+i];
4815             }
4816             for (i=0; i < s; i++) nowim[i] = a_rot[i];
4817          }
4818       }
4819       rot_nr += rot_direct;
4820       if ( avr_grp ) Put_image(Im_Nr);  /* put average image after all rot */
4821    }
4822    else if ( rot_direct == -1 ) {            /* counterclockwise rotation */
4823       nowim = SAR(Im_Nr) ; k = DIM(Im_Nr) ; l = k-1 ; s = SIZ(Im_Nr) ;
4824       for (i=0; i < k; i++) {          /* rotate and redisplay actual one */
4825          m = i * k;
4826          for (j=0; j < k; j++)
4827             a_rot[m+j] = nowim[(j+1)*k-i-1];
4828       }
4829       for (i=0; i < s; i++) nowim[i] = a_rot[i];
4830 
4831       if( ! kROT_doall ){
4832          Put_image(Im_Nr ) ;
4833          return 0;
4834       }
4835 
4836       if ( diff_im && Im_Nr < npoints ) {  /* rotate reference array too */
4837          for (i=0; i < k; i++) {
4838             m = i * k;
4839             for (j=0; j < k; j++)
4840                a_rot[m+j] = ref_ar[(j+1)*k-i-1];
4841          }
4842          for (i=0; i < s; i++) ref_ar[i] = a_rot[i];
4843       }
4844       if ( !avr_grp ) Put_image(Im_Nr);         /* put single image here */
4845                                                      /* rotate other data */
4846       for (n=0; n < N_im; n++) {
4847          nowim = SAR(n) ; k = DIM(n) ; l = k-1 ; s = SIZ(n) ;
4848          if ( n != Im_Nr ) {
4849             for (i=0; i < k; i++) {
4850                m = i * k;
4851                for (j=0; j < k; j++)
4852                   a_rot[m+j] = nowim[(j+1)*k-i-1];
4853             }
4854             for (i=0; i < s; i++) nowim[i] = a_rot[i];
4855          }
4856       }
4857       rot_nr += rot_direct;
4858       if ( avr_grp ) Put_image(Im_Nr);  /* put average image after all rot */
4859    }
4860 
4861         if( rot_nr ==  3 ) rot_nr = -1 ;
4862    else if( rot_nr == -3 ) rot_nr =  1 ;
4863 
4864    redraw_graph();
4865    DrawSubWindow();
4866    return 0;
4867 }
4868 
4869 /* ----------------- */
4870    int
Smooth_line(ikey)4871    Smooth_line(ikey)
4872    int ikey;
4873 /* ----------------- */
4874 {
4875    int  i, x, y, hx;
4876    char *cpt, str[100];
4877    float fval, fmax, f0, f1, f2;
4878 
4879    if ( txtW_ON ) {
4880       XBell(theDisp, 100); return(2);
4881    }
4882 
4883    i = (MAX_SMOOTH - 1) / 10; /* +- 5 sigma range */
4884    fmax = i;
4885    sprintf(str, "Enter sigma value [.1-%d]:", i);
4886    txtW_ON = 1;
4887 
4888    x = 50 + GL_DLX;
4889    y = 50 + GT_DLY;
4890 
4891    strp[0] = ASC_NUL ;
4892    take_file_name(theDisp, GWindow , CMap, txtGC, mfinfo, x, y, strp, 41,
4893                   str, 0);
4894 
4895    fval = strtod( strp , &cpt ) ;
4896    if( *cpt != ASC_NUL || fval < .1 || fval > fmax ) {
4897       fprintf(stderr,
4898          "\n*** Sigma valule out of range [.1-%d] %s!\n" , (int) fmax, strp ) ;
4899       AJ_sigma = -1.;
4900       XBell(theDisp, 100);
4901    }
4902    else {
4903       AJ_sigma = fval ;
4904    }
4905    AJ_norm = 1.;
4906    if ( AJ_sigma > 0. ) {
4907       f2 = 0;
4908       AJ_nr = (int) (10.*AJ_sigma +.5);
4909       if ( AJ_nr%2 ) AJ_nr++;
4910       if ( AJ_nr < 4) AJ_nr = 4;
4911       hx = AJ_nr / 2;
4912       f0 = 1. / (2.* AJ_sigma  * AJ_sigma);
4913       for (i=0; i <= AJ_nr; i++) { /* make symmetrical gauss function */
4914          f1 = (float) ((i-hx)*(i-hx));
4915          AJ_gauss[i] = exp(-f1*f0);
4916          f2 += AJ_gauss[i];
4917       }
4918       if ( f2 != 0. ) AJ_norm = 1./ f2;
4919    }
4920 
4921    txtW_ON = 0;
4922    redraw_graph();
4923    DrawSubWindow();
4924 
4925    return(0);
4926 }
4927 
4928 /* ----------------- */
4929    int
get_fft_mag(fff)4930    get_fft_mag(fff)
4931    float *fff;
4932 /* ----------------- */
4933 {
4934    int  i, k, x, y;
4935    char *cpt, str[100];
4936    float fval, fmax, fmin, f0, f1, f2, f3;
4937    int   max1;
4938 
4939    fmax = 100.;
4940    fmin = .01;
4941    if ( txtW_ON ) {
4942       XBell(theDisp, 100); return(2);
4943    }
4944 
4945    f0 = *fff / FFT_MAG;
4946    sprintf(str, "Enter new FT scale value [%g-%g]: %g", fmin, fmax, f0);
4947    txtW_ON = 1;
4948 
4949    x = 50 + GL_DLX;
4950    y = 50 + GT_DLY;
4951 
4952    strp[0] = ASC_NUL ;
4953    take_file_name(theDisp, GWindow , CMap, txtGC, mfinfo, x, y, strp, 46,
4954                   str, 0);
4955 
4956    fval = strtod( strp , &cpt ) ;
4957    if( *cpt != ASC_NUL || fval < fmin || fval > fmax ) {
4958       fprintf(stderr,
4959          "\n*** FT scale value out of range [%g-%g]: %s!\n", fmin, fmax, strp);
4960       XBell(theDisp, 100);
4961       txtW_ON = 0;
4962       redraw_graph();
4963       DrawSubWindow();
4964       return (0);
4965    }
4966    else {
4967       *fff = fval * FFT_MAG;
4968    }
4969    f0 = *fff;
4970    for (i=0; i < FT_disp; i++) {
4971       for (j=0; j < ar_size; j++) {
4972          f1 = c_arr[i+1+j*FT_dim].r; /* no zero component here */
4973          f2 = c_arr[i+1+j*FT_dim].i;
4974          f3 = f0 * sqrt(f1*f1 + f2*f2);
4975          if ( f3 > 32767. ) f3 = 32767.;
4976          SAR(i)[j] = f3;
4977       }
4978    }
4979    min1 =  32767;
4980    max1 = -32768;
4981    for (k=0; k < npoints; k++) { /* find global min and max */
4982       nowim = SAR(k) ;
4983       for (i=0; i < ar_size; i++) {
4984          if ( nowim[i] < min1 ) min1 = nowim[i] ;
4985          if ( nowim[i] > max1 ) max1 = nowim[i] ;
4986       }
4987    }
4988    del1 = max1 - min1;
4989    if (del1 < 1.) del1 = 1.;
4990    coef1 = ( (float) NC - 1.) / del1;
4991 
4992    old_im = -1;
4993    Put_image(Im_Nr);                      /* reload actual image */
4994    txtW_ON = 0;
4995    redraw_graph();
4996    DrawSubWindow();
4997 
4998    return(0);
4999 }
5000 /* ------------ */
5001    int
FFT_action()5002    FFT_action()
5003 /* ------------ */
5004 {
5005    MRI_IMAGE **MM;
5006    int i;
5007    float *VV;
5008 
5009    if ( Im_Nr >= npoints) {
5010       Im_Nr = 0;
5011       XClearWindow(theDisp, GWindow);
5012       Put_image(Im_Nr);
5013       DrawSubWindow();
5014       DrawTopWindow();
5015       discard(KeyPressMask, event);
5016    }
5017 
5018    if( FFT_pressed ) {                /* second press - back to normal graph */
5019       FT1_pressed = 0;
5020       FFT_pressed = 0 ;
5021       FT_graph_on = 0;
5022       xtkeys[kFFT].st = key_kFFT_FFT;
5023       DrawKey(kFFT) ;                  /* restore key label */
5024       FT2_stat = 0;
5025       z_imL = z_im1 = 0;
5026       if ( FT_done ) {
5027          int   mm, min_im = 0;
5028          float ff;
5029 
5030          if ( undo_buf != NULL ) {
5031             free(undo_buf);
5032             act_undo = -1;
5033          }
5034          if ( undo_ref != NULL ) {
5035             free(undo_ref);
5036             ref_undo = -1;
5037          }
5038          if ( RWC_ideal != NULL  && RWC_ideal->len >= npoints ) {
5039             VV = RWC_ideal->ts; RWC_ideal->ts = T_ref; T_ref = VV;
5040          }
5041          MM = allim;     allim = t_allim;   t_allim = MM;
5042          mm = N_im;       N_im = t_N_im;     t_N_im = mm;
5043          mm = npoints; npoints = t_points; t_points = mm;
5044          mm = min1;       min1 = t_min1;     t_min1 = mm;
5045          ff = coef1;     coef1 = t_coef1;   t_coef1 = ff;
5046          if ( grid_timed ) if ( grid_coef < .5 ) grid_coef = GRID_COEF;
5047          Im_Nr = min_im;
5048          FT_grid = 0;
5049          redraw_graph();   /* draw frame and text in it */
5050          DrawSubWindow();
5051          DrawTopWindow();
5052          old_im = -1;
5053          Put_image(0);                      /* put the first image */
5054       }
5055       if ( cancell_FT ) {
5056          cancell_FT = 0;
5057          FT_done = 0;
5058          free(c_arr);
5059          c_arr = NULL;
5060          free(r_arr);
5061          r_arr = NULL;
5062       }
5063       FT3_stat = FT_done;
5064       xtkeys[kFT1].st = key_kFT1[FT1_pressed];
5065       xtkeys[kFT2].st = key_kFT2[FT2_stat];
5066       xtkeys[kFT3].st = key_kFT3[FT3_stat];
5067       for(i=FFT_first_key; i <= FFT_last_key; i++)
5068          XUnmapWindow(theDisp,  key[i].wid);  /* second press */
5069    }
5070    else {                            /* first press */
5071       FFT_pressed  = 1;
5072       xtkeys[kFFT].st = key_kFFT_noFT;
5073       DrawKey(kFFT);
5074       FT3_stat = FT_done;
5075       if ( FT_done ) {
5076          int   mm, min_im = 0;
5077          float ff;
5078 
5079          for(i=FFT_first_key; i <= FFT_last_key; i++)
5080             XMapWindow  (theDisp,  key[i].wid);  /* first press & FFT done */
5081 
5082          FT_graph_on = 1;
5083          if ( RWC_ideal != NULL  && RWC_ideal->len >= npoints ) {
5084             VV = RWC_ideal->ts; RWC_ideal->ts = T_ref; T_ref = VV;
5085          }
5086          MM = allim;     allim = t_allim;   t_allim = MM;
5087          mm = N_im;       N_im = t_N_im;     t_N_im = mm;
5088          mm = npoints; npoints = t_points; t_points = mm;
5089          mm = min1;       min1 = t_min1;     t_min1 = mm;
5090          ff = coef1;     coef1 = t_coef1;   t_coef1 = ff;
5091          FT_grid = GRID_NUM;
5092          if ( grid_timed ) if ( grid_coef > 2. ) grid_coef = 1. / GRID_COEF;
5093          Im_Nr = min_im;
5094          redraw_graph();   /* draw frame and text in it */
5095          DrawSubWindow();
5096          DrawTopWindow();
5097          old_im = -1;
5098          Put_image(0);                      /* put the first image */
5099       }
5100       else {
5101          for(i=FFT_first_key + 1; i <= FFT_last_key; i++)
5102             XMapWindow  (theDisp,  key[i].wid);  /* first press & no FFT */
5103       }
5104    }
5105    return 0;
5106 }
5107 
5108 /* ------------------- */
5109    int
FFT_selection(ikey)5110    FFT_selection(ikey)
5111    int ikey;
5112 /* ------------------- */
5113 {
5114    int  i, j, k, ii, mm, nn;
5115    int  fun_modified;
5116 
5117    fun_modified = 0;
5118 
5119    switch( ikey ) {
5120       /* toggle edit Function - end of Edit button */
5121       case kFT1:
5122          FT1_pressed = 1 - FT1_pressed;
5123          InvertKey(kFT1);
5124          xtkeys[kFT1].st = key_kFT1[FT1_pressed];
5125          if ( FT1_pressed ) {                    /* edit mode */
5126             FT2_stat = 1;
5127             z_imL = z_im1 = 0;
5128             FT3_stat = 2;
5129             xtkeys[kFT2].st = key_kFT2[FT2_stat];
5130             xtkeys[kFT3].st = key_kFT3[FT3_stat];
5131          }
5132          else {
5133             FT2_stat = 0;
5134             FT3_stat = FT_done;
5135             z_imL = z_im1 = 0;
5136             xtkeys[kFT2].st = key_kFT2[FT2_stat];
5137             xtkeys[kFT3].st = key_kFT3[FT3_stat];
5138          }
5139          DrawKey(kFT1);
5140          DrawKey(kFT2);
5141          DrawKey(kFT3);
5142       break ;  /* end of ikey=kFT1 */
5143 
5144       case kFT2:
5145          /* make FFT - when not in edit and FT2 = "FT" */
5146          if ( (FT1_pressed == 0) && (FT2_stat == 0) ) {
5147             register float f0, f1, f2, f3;
5148             int min_im = 0, max1;
5149             int Fnx = allim[0]->nx;
5150             int Fny = allim[0]->ny;
5151 
5152             if ( c_arr == NULL ) {
5153                FT_dim = 2;
5154                while ( FT_dim < npoints ) FT_dim *= 2;
5155                FT_disp = FT_dim / 2;
5156                im_f = min(3, dec_indx(FT_disp)-1);  /* 2d index in formt[][] */
5157                FT_size = FT_dim * ar_size;
5158                c_arr = (complex *) malloc(sizeof(complex) * FT_size);
5159                if( c_arr == NULL ){
5160                   fprintf(stderr,"\n*** cannot malloc c_arr\a\n") ;
5161                   XBell(theDisp, 100); return(1);
5162                }
5163                /* load complex array for FFT */
5164                for (i=0; i < ar_size; i++) {
5165                   ii = i * FT_dim;
5166                   for (j=0; j < npoints; j++) {
5167                      c_arr[ii+j].r = SAR(j)[i];
5168                      c_arr[ii+j].i = 0.;
5169                   }
5170                   for (j=npoints; j < FT_dim; j++) {
5171                      c_arr[ii+j].r = SAR(npoints-1)[i];
5172                      c_arr[ii+j].i = 0.;
5173                   }
5174                }
5175             }
5176             if ( r_arr == NULL ) {
5177                r_arr = (complex *) malloc(sizeof(complex) * FT_dim);
5178                if( r_arr == NULL ){
5179                   fprintf(stderr,"\n*** cannot malloc r_arr\a\n") ;
5180                   XBell(theDisp, 100); return(1);
5181                }
5182                /* load complex reference array for FFT */
5183                if ( RWC_ideal != NULL  && RWC_ideal->len >= npoints ) {
5184                   for (j=0; j < npoints; j++) {
5185                      r_arr[j].r = RWC_ideal->ts[j];
5186                      r_arr[j].i = 0.;
5187                   }
5188                   for (j=npoints; j < FT_dim; j++) {
5189                      r_arr[j].r = RWC_ideal->ts[npoints-1];
5190                      r_arr[j].i = 0.;
5191                   }
5192                }
5193                else {
5194                   for (j=0; j < FT_dim; j++) {
5195                      r_arr[j].r = 0.;
5196                      r_arr[j].i = 0.;
5197                   }
5198                }
5199             }
5200             csfft( -1, FT_dim, r_arr);    /* FT of reference line */
5201             for (i=0; i < ar_size; i++) {
5202                if ( i%100 == 0 ) {
5203                   printf(".");
5204                   fflush(stdout);
5205                }
5206                ii = i * FT_dim;
5207                csfft( -1, FT_dim, &c_arr[ii]);
5208             }
5209             if ( RWC_ideal != NULL  && RWC_ideal->len >= npoints ) {
5210                T_ref = RWC_ideal->ts;
5211                RWC_ideal->ts = NULL;
5212                RWC_ideal->ts = (float *) malloc( sizeof(float) * FT_disp);
5213                if( RWC_ideal->ts == NULL ) {
5214                   fprintf(stderr,
5215                      "\n*** cannot malloc RWC_ideal->ts for FT\a\n");
5216                   XBell(theDisp, 100);
5217                   DrawKey(kFT3);
5218                   return(2);
5219                }
5220             }
5221             t_allim = allim; t_N_im = N_im; t_points = npoints;
5222             N_im = npoints = FT_disp;
5223             allim = NULL;
5224             Im_Nr = min_im;
5225             allim = (MRI_IMAGE **) malloc( sizeof(MRI_IMAGE *) * FT_disp);
5226             if( allim == NULL ) {
5227                fprintf(stderr,"\n*** cannot malloc allim\a\n") ;
5228                XBell(theDisp, 100);
5229                DrawKey(kFT3);
5230                return(2);
5231             }
5232             for (i=0; i < FT_disp; i++) {
5233                allim[i] = mri_new( Fnx, Fny, MRI_short );
5234                if( allim == NULL ) {
5235                   fprintf(stderr,"\n*** cannot malloc allim[%d] in FT\a\n", i) ;
5236                   XBell(theDisp, 100); return(2);
5237                }
5238                sprintf(FT_name, formt[0][im_f], "FT", i+1);
5239                mri_add_name( FT_name, allim[i]);
5240             }
5241             XMapWindow  (theDisp,  key[FFT_first_key].wid); /* can edit now */
5242             f0 = fft_mag;
5243             for (i=0; i < FT_disp; i++) {
5244                for (j=0; j < ar_size; j++) {
5245                   f1 = c_arr[i+1+j*FT_dim].r; /* no zero component here */
5246                   f2 = c_arr[i+1+j*FT_dim].i;
5247                   f3 = f0 * sqrt(f1*f1 + f2*f2);
5248                   if ( f3 > 32767. ) f3 = 32767.;
5249                   SAR(i)[j] = f3;
5250                }
5251             }
5252             if ( RWC_ideal != NULL  && RWC_ideal->len >= npoints ) {
5253                for (i=0; i < FT_disp; i++) {
5254                   f1 = r_arr[i+1].r; /* no zero component for reference too */
5255                   f2 = r_arr[i+1].i;
5256                   f3 = f0 * sqrt(f1*f1 + f2*f2);
5257                   if ( f3 > 32767. ) f3 = 32767.;
5258                   RWC_ideal->ts[i] = f3;
5259                }
5260             }
5261             t_min1 = min1; t_coef1 = coef1;
5262             min1 =  32767;
5263             max1 = -32768;
5264             for (k=0; k < npoints; k++) { /* find global min and max */
5265                nowim = SAR(k) ;
5266                for (i=0; i < ar_size; i++) {
5267                   if ( nowim[i] < min1 ) min1 = nowim[i] ;
5268                   if ( nowim[i] > max1 ) max1 = nowim[i] ;
5269                }
5270             }
5271             del1 = max1 - min1;
5272             if (del1 < 1.) del1 = 1.;
5273             coef1 = ( (float) NC - 1.) / del1;
5274 
5275             FT_grid = GRID_NUM;
5276             if ( grid_timed ) {
5277                f0 = 2. * (float) FT_disp / grid_far[0];
5278                grid_far[GRID_NUM]   = f0;
5279                grid_far[GRID_NUM+1] = 2.*f0;
5280                grid_far[GRID_NUM+2] = 5.*f0;
5281                if ( grid_coef > 2. ) grid_coef = 1. / GRID_COEF;
5282             }
5283 
5284             FT_graph_on = 1;
5285             redraw_graph();   /* draw frame and text in it */
5286             DrawSubWindow();
5287             DrawTopWindow();
5288             old_im = -1;
5289             Put_image(0);                      /* put the first image */
5290 
5291             FT3_stat = FT_done = 1;;
5292             xtkeys[kFT3].st = key_kFT3[FT3_stat];
5293             DrawKey(kFT3);
5294          }
5295          /* edit mode on and FT2 = "0..0" */
5296          else if ( (FT1_pressed == 1) && (FT2_stat == 1) ) {
5297             FT2_stat = 2;
5298             xtkeys[kFT2].st = key_kFT2[FT2_stat];
5299             DrawKey(kFT2);
5300          }
5301          else if ( (FT1_pressed == 1) && (FT2_stat == 2) ) {
5302             z_im1 = Im_Nr;
5303             FT2_stat = 3;
5304             xtkeys[kFT2].st = key_kFT2[FT2_stat];
5305             DrawKey(kFT2);
5306          }
5307          else if ( (FT1_pressed == 1) && (FT2_stat == 3) ) {
5308             int i, j, k, mm, nn;
5309 
5310             z_imL = Im_Nr + 1;
5311             /* swap order if last < first */
5312             if ( z_imL - z_im1 < 0) {
5313                i = z_im1;
5314                z_im1 = z_imL;
5315                z_imL = i;
5316             }
5317             mm = act_undo + 1;
5318             act_undo += (z_imL - z_im1) * ar_size;
5319             undo_buf = realloc(undo_buf, (act_undo+1)*sizeof(struct _undo_buf));
5320             if ( undo_buf != NULL ) {
5321                for ( k=z_im1, nn=mm; k < z_imL; k++, nn+=ar_size) {
5322                   for ( i=0, j=nn; i < ar_size; j++, i++) {
5323                      undo_buf[j].im  = k;
5324                      undo_buf[j].pix = i;
5325                      undo_buf[j].r   = c_arr[i*FT_dim+k+1].r;
5326                      undo_buf[j].i   = c_arr[i*FT_dim+k+1].i;
5327                      undo_buf[j].r2  = c_arr[(i+1)*FT_dim-k-1].r;
5328                      undo_buf[j].i2  = c_arr[(i+1)*FT_dim-k-1].i;
5329                      SAR(k)[i]   = 0;
5330                      c_arr[i*FT_dim+k+1].r     = 0.;
5331                      c_arr[i*FT_dim+k+1].i     = 0.;
5332                      c_arr[(i+1)*FT_dim-k-1].r = 0.;
5333                      c_arr[(i+1)*FT_dim-k-1].i = 0.;
5334                   }
5335                }
5336             }
5337             if ( RWC_ideal != NULL  && RWC_ideal->len >= npoints ) {
5338                mm = ref_undo + 1;
5339                ref_undo += (z_imL - z_im1);
5340                undo_ref =
5341                       realloc(undo_ref, (ref_undo+1)*sizeof(struct _undo_buf));
5342                if ( undo_ref != NULL ) {
5343                   for ( k=z_im1, j=mm; k < z_imL; k++, j++) {
5344                      undo_ref[j].im  = k;
5345                      undo_ref[j].r   = r_arr[k+1].r;
5346                      undo_ref[j].i   = r_arr[k+1].i;
5347                      undo_ref[j].r2  = r_arr[FT_dim-k-1].r;
5348                      undo_ref[j].i2  = r_arr[FT_dim-k-1].i;
5349                      RWC_ideal->ts[k] = 0;
5350                      r_arr[k+1].r     = 0.;
5351                      r_arr[k+1].i     = 0.;
5352                      r_arr[FT_dim-k-1].r = 0.;
5353                      r_arr[FT_dim-k-1].i = 0.;
5354                   }
5355                }
5356             }
5357             redraw_graph() ;
5358             DrawSubWindow();
5359             old_im = -1;
5360             Put_image(Im_Nr);
5361             FT2_stat = 1;
5362             z_imL = z_im1 = 0;
5363             xtkeys[kFT2].st = key_kFT2[FT2_stat];
5364             DrawKey(kFT2);
5365          }
5366       break ;  /* end of ikey=kFT2 */
5367 
5368       /* make inv FFT */
5369       case kFT3:
5370          /* make inverse FFT */
5371          if ( (FT1_pressed == 0) && (FT_done == 1) ) {
5372             MRI_IMAGE **MM;
5373             int   min_im = 0, max1;
5374             register float f0, f1, f2, f3, f4, fpi2;
5375 
5376             im_f = min(3, dec_indx(npoints)-1);  /* 2d index in formt[][] */
5377 
5378             f0 = 1. / (float) FT_dim;
5379             for (i=0; i < ar_size; i++) {
5380                if ( i%100 == 0 ) {
5381                   printf(".");
5382                   fflush(stdout);
5383                }
5384                ii = i * FT_dim;
5385                csfft(1, FT_dim, &c_arr[ii]);
5386             }
5387             csfft(1, FT_dim, r_arr);
5388 
5389             MM = allim;     allim = t_allim;   t_allim = MM;
5390             mm = N_im;       N_im = t_N_im;     t_N_im = mm;
5391             mm = npoints; npoints = t_points; t_points = mm;
5392             if ( grid_timed ) if ( grid_coef < .5 ) grid_coef = GRID_COEF;
5393 
5394             fpi2 = .5 * PI;
5395             for (i=0; i < ar_size; i++) {
5396                ii = i * FT_dim;
5397                for (j=0; j < npoints; j++) {
5398                   f1 = c_arr[ii+j].r *= f0;;
5399                   f2 = c_arr[ii+j].i *= f0;;
5400                   f3 = sqrt(f1*f1 + f2*f2);
5401                   if ( f3 > 32767. ) f3 = 32767.;
5402                   if ( phase ) {
5403                      f4 = atan2(f2, f1);
5404                      if ( (f4 < fpi2) && (f4 > -fpi2) ) SAR(j)[i] =  f3;
5405                      else                               SAR(j)[i] = -f3;
5406                   }
5407                   else {
5408                      SAR(j)[i] = f3;
5409                   }
5410                }
5411             }
5412             if ( RWC_ideal != NULL  && RWC_ideal->len >= npoints ) {
5413                for (j=0; j < npoints; j++) {
5414                   f1 = r_arr[j].r *= f0;;
5415                   f2 = r_arr[j].i *= f0;;
5416                   f3 = sqrt(f1*f1 + f2*f2);
5417                   if ( f3 > 32767. ) f3 = 32767.;
5418                   if ( phase ) {
5419                      f4 = atan2(f2, f1);
5420                      if ( (f4 < fpi2) && (f4 > -fpi2) ) RWC_ideal->ts[j] =  f3;
5421                      else                               RWC_ideal->ts[j] = -f3;
5422                   }
5423                   else {
5424                      RWC_ideal->ts[j] = f3;
5425                   }
5426                }
5427             }
5428             t_min1 = min1; t_coef1 = coef1;
5429             min1 =  32767;
5430             max1 = -32768;
5431             for (k=0; k < npoints; k++) { /* find global min and max */
5432                nowim = SAR(k) ;
5433                for (i=0; i < ar_size; i++) {
5434                   if ( nowim[i] < min1 ) min1 = nowim[i] ;
5435                   if ( nowim[i] > max1 ) max1 = nowim[i] ;
5436                }
5437             }
5438             del1 = max1 - min1;
5439             if (del1 < 1.) del1 = 1.;
5440             coef1 = ( (float) NC - 1.) / del1;
5441 
5442             Im_Nr = min_im;
5443             FT_grid = 0;
5444             redraw_graph();   /* draw frame and text in it */
5445             DrawSubWindow();
5446             DrawTopWindow();
5447             old_im = -1;
5448             Put_image(0);                      /* put the first image */
5449 
5450             for(i=FFT_first_key; i <= FFT_last_key; i++)
5451                XUnmapWindow(theDisp,  key[i].wid);  /* as second press */
5452 
5453             xtkeys[kFFT].st = key_kFFT_FFT;
5454             DrawKey(kFFT) ;                  /* restore key label */
5455             xtkeys[kFT1].st = key_kFT1[FT1_pressed];
5456             xtkeys[kFT2].st = key_kFT2[FT2_stat];
5457             xtkeys[kFT3].st = key_kFT3[FT3_stat];;
5458             FT1_pressed = 0;
5459             FFT_pressed = 0 ;
5460             FT_graph_on = 0;
5461             FT_done = 0;
5462             free(c_arr);
5463             c_arr = NULL;
5464          }
5465          /* edit mode on and FT3 pressed = "zero" */
5466          else if ( FT1_pressed == 1 ) {
5467             nn = act_undo + 1;
5468             act_undo += ar_size;
5469             undo_buf = realloc(undo_buf, (act_undo+1)*sizeof(struct _undo_buf));
5470             if ( RWC_ideal != NULL  && RWC_ideal->len >= npoints ) {
5471                ref_undo += 1;
5472                undo_ref =
5473                       realloc(undo_ref, (ref_undo+1)*sizeof(struct _undo_buf));
5474                if ( undo_ref != NULL ) {
5475                   j = ref_undo;
5476                   undo_ref[j].im  = Im_Nr;
5477                   undo_ref[j].r   = r_arr[Im_Nr+1].r;
5478                   undo_ref[j].i   = r_arr[Im_Nr+1].i;
5479                   undo_ref[j].r2  = r_arr[FT_dim-Im_Nr-1].r;
5480                   undo_ref[j].i2  = r_arr[FT_dim-Im_Nr-1].i;
5481                   RWC_ideal->ts[Im_Nr] = 0;
5482                   r_arr[Im_Nr+1].r     = 0.;
5483                   r_arr[Im_Nr+1].i     = 0.;
5484                   r_arr[FT_dim-Im_Nr-1].r = 0.;
5485                   r_arr[FT_dim-Im_Nr-1].i = 0.;
5486                }
5487             }
5488             if ( undo_buf != NULL ) {
5489                for ( i=0, j=nn; i < ar_size; j++, i++) {
5490                   undo_buf[j].im  = Im_Nr;
5491                   undo_buf[j].pix = i;
5492                   undo_buf[j].r   = c_arr[i*FT_dim+Im_Nr+1].r;
5493                   undo_buf[j].i   = c_arr[i*FT_dim+Im_Nr+1].i;
5494                   undo_buf[j].r2  = c_arr[(i+1)*FT_dim-Im_Nr-1].r;
5495                   undo_buf[j].i2  = c_arr[(i+1)*FT_dim-Im_Nr-1].i;
5496                   SAR(Im_Nr)[i]   = 0;
5497                   c_arr[i*FT_dim+Im_Nr+1].r     = 0.;
5498                   c_arr[i*FT_dim+Im_Nr+1].i     = 0.;
5499                   c_arr[(i+1)*FT_dim-Im_Nr-1].r = 0.;
5500                   c_arr[(i+1)*FT_dim-Im_Nr-1].i = 0.;
5501                }
5502                redraw_graph() ;
5503                DrawSubWindow();
5504             }
5505             old_im = -1;
5506             Put_image(Im_Nr);
5507          }
5508       break ;  /* end of ikey=kFT3 */
5509 
5510    }  /* end of ikey switch */
5511 
5512    if( fun_modified ){
5513       redraw_graph() ;
5514       fun_modified = 0;
5515    }
5516 
5517    return 0;
5518 }
5519 
5520 /* ------------- */
5521    int
Im_diff(ikey)5522    Im_diff(ikey)
5523    int ikey;
5524 /* ------------- */
5525 {
5526    XUnmapWindow(theDisp,  key[kDIF].wid);
5527    XMapWindow  (theDisp,  key[kIR1].wid);
5528    XMapWindow  (theDisp,  key[kIR2].wid);
5529    return 0;
5530 }
5531 
5532 /* ---------------- */
SCA_action(ikey)5533    int SCA_action(ikey)
5534    int ikey;
5535 /* ---------------- */
5536 {
5537    int i;
5538 
5539    if ( SCA_pressed == 0 ) SCA_pressed = 1;
5540    else SCA_pressed = 0;
5541 
5542    xtkeys[kSCA].st = key_kSCA[SCA_pressed];
5543    DrawKey(kSCA);
5544 //   XMapWindow  (theDisp,  key[kSCA].wid);
5545 
5546    if ( SCA_pressed ) {                /* first press */
5547       xtkeys[kSCA].st = key_kSCA[SCA_pressed];
5548       DrawKey(kSCA);
5549       for(i=SCA_first_key; i <= SCA_last_key; i++)
5550          XMapWindow  (theDisp,  key[i].wid);
5551    }
5552    else {
5553       for(i=SCA_first_key; i <= SCA_last_key; i++)
5554          XUnmapWindow(theDisp,  key[i].wid);  /* second press */
5555    }
5556 #if 0
5557          redraw_graph();   /* draw frame and text in it */
5558          DrawSubWindow();
5559          DrawTopWindow();
5560          old_im = -1;
5561          Put_image(0);                      /* put the first image */
5562       }
5563       else {
5564          for(i=FFT_first_key + 1; i <= FFT_last_key; i++)
5565             XMapWindow  (theDisp,  key[i].wid);  /* first press & no FFT */
5566       }
5567 
5568 
5569 
5570 
5571       FT1_pressed = 0;
5572       FFT_pressed = 0 ;
5573       FT_graph_on = 0;
5574       xtkeys[kFFT].st = key_kFFT_FFT;
5575       DrawKey(kFFT) ;                  /* restore key label */
5576       FT2_stat = 0;
5577       FT3_stat = FT_done;
5578       xtkeys[kFT1].st = key_kFT1[FT1_pressed];
5579       xtkeys[kFT2].st = key_kFT2[FT2_stat];
5580       xtkeys[kFT3].st = key_kFT3[FT3_stat];
5581       for(i=FFT_first_key; i <= FFT_last_key; i++)
5582          XUnmapWindow(theDisp,  key[i].wid);  /* second press */
5583    }
5584    else {                            /* first press */
5585       FFT_pressed  = 1;
5586       xtkeys[kFFT].st = key_kFFT_noFT;
5587       DrawKey(kFFT);
5588 
5589 
5590    else {
5591          redraw_graph();   /* draw frame and text in it */
5592          DrawSubWindow();
5593          DrawTopWindow();
5594          old_im = -1;
5595          Put_image(0);
5596    }
5597 #endif
5598 
5599    return 0;
5600 }
5601 
5602 
5603 /* ------------------- */
5604    int
SCA_selection(ikey)5605    SCA_selection(ikey)
5606    int ikey ;
5607 /* ------------------- */
5608 {
5609    int i, k, ix, iy;
5610    float f0;
5611 
5612    f0 = 0.;
5613    switch( ikey ){
5614       case kSC1:
5615          for (ix=0;ix<matx;ix++) {
5616             for (iy=0;iy<maty;iy++) {
5617                f0 += val[ix][iy][Im_Nr];
5618             }
5619          }
5620          f0 = f0 / (float) (matx*maty);
5621          SCA_ref_val = f0;
5622          printf("AJ REF im %d,  Box avr: %.1f\n", Im_Nr + 1, f0);
5623 
5624       break;
5625       case kSC2:
5626          if ( SCA_ref_val < 0.000001 ) {
5627             printf("!!! No reference image chosen yet (ref val: %g) !!!\n", SCA_ref_val);
5628             return -1;
5629          }
5630          for (ix=0;ix<matx;ix++) {
5631             for (iy=0;iy<maty;iy++) {
5632                f0 += val[ix][iy][Im_Nr];
5633             }
5634          }
5635          f0 = f0 / (float) (matx*maty);
5636          if ( f0 < 0.000001 ) SCA_ratio = 1.;
5637          else                 SCA_ratio = SCA_ref_val / f0;
5638          printf("AJ IMAGE Box avr: %.1f, coef: %g\n", f0, SCA_ratio);
5639 
5640          nowim = SAR(Im_Nr) ; k = SIZ(Im_Nr) ;
5641          for (i=0; i < k; i++) nowim[i] = (int) ( ((float) nowim[i]) *SCA_ratio + .5 );
5642 
5643          XClearWindow(theDisp, GWindow);
5644          Put_image(Im_Nr);
5645          redraw_graph();
5646          DrawSubWindow();
5647          DrawTopWindow();
5648       break;
5649    }
5650 
5651    return 0;
5652 }
5653 
5654 /* ------------- */
5655    int
Im_Aver(ikey)5656    Im_Aver(ikey)
5657    int ikey;
5658 /* ------------- */
5659 {
5660    avr_grp = fim_avr = 0;
5661    XMapWindow(theDisp,  key[kAV1].wid);
5662    XMapWindow(theDisp,  key[kAV2].wid);
5663    return 0;
5664 }
5665 
5666 /* ------------- */
5667    int
Im_norm(ikey)5668    Im_norm(ikey)
5669    int ikey;
5670 /* ------------- */
5671 {
5672    diff_im = fim_dif = 0;
5673    avr_grp = fim_avr = 0;
5674    Av_length = 1;
5675    XUnmapWindow(theDisp,  key[kNRM].wid);
5676    XMapWindow  (theDisp,  key[kDIF].wid);
5677    old_im = -1;            /* to avoid faster reload of old data */
5678    Put_image(Im_Nr);
5679    redraw_graph();
5680    DrawSubWindow();
5681    return 0;
5682 }
5683 
5684 /* ------------ */
5685    int
Av_im1(ikey)5686    Av_im1(ikey)
5687    int ikey;
5688 /* ------------ */  /* set first image for average one */
5689 {
5690    Av_1 = Im_Nr;
5691    av1_done = 1;
5692    return 0;
5693 }
5694 
5695 /* ------------ */
5696    int
Av_im2(ikey)5697    Av_im2(ikey)
5698    int ikey;
5699 /* ------------ */  /* set second image for average one */
5700 {
5701    register int  i, j;
5702 
5703    if ( av1_done ) {
5704       Av_2 = Im_Nr;
5705       if ( Av_2 < Av_1 ) {
5706          i = Av_2; Av_2 = Av_1; Av_1 = i;
5707       }
5708       Im_Nr = Av_1;
5709    }
5710    else     Av_1 = Av_2 = Im_Nr;
5711 
5712    for (i=0; i< ar_size; i++) av_ar[i] = 0;
5713    for (i=0; i < ar_size; i++) {
5714       for (j=Av_1; j <= Av_2; j++) av_ar[i] += SAR(j)[i] ;
5715    }
5716    Av_length =  Av_2 - Av_1 + 1;
5717    for (i=0; i < ar_size; i++) av_ar[i] = av_ar[i] / Av_length;
5718 
5719    XUnmapWindow(theDisp,  key[kAV1].wid);
5720    XUnmapWindow(theDisp,  key[kAV2].wid);
5721    XMapWindow  (theDisp,  key[kNRM].wid);
5722    avr_grp = fim_avr = 1;
5723    av1_done = 0;
5724    old_im = -1;            /* to avoid faster reload of old data */
5725    Put_image(Im_Nr);
5726    redraw_graph();
5727    DrawSubWindow();
5728    return 0;
5729 }
5730 
5731 /* ------------- */
5732    int
Ref_im1(ikey)5733    Ref_im1(ikey)
5734    int ikey;
5735 /* ------------- */  /* set first image for average reference one */
5736 {
5737    Im_1 = Im_Nr;
5738    im1_done = 1;
5739    return 0;
5740 }
5741 
5742 /* ------------- */
5743    int
Ref_im2(ikey)5744    Ref_im2(ikey)
5745    int ikey;
5746 /* -------------  set second image for average and make refer im for diff */
5747 {
5748    register int  i, j, m;
5749 
5750    if ( im1_done ) {
5751       Im_2 = Im_Nr;
5752       if ( Im_2 < Im_1 ) {
5753          i = Im_2; Im_2 = Im_1; Im_1 = i;
5754       }
5755    }
5756    else     Im_1 = Im_2 = Im_Nr;
5757 
5758    for (i=0; i< ar_size; i++) ref_ar[i] = 0;
5759    for (i=0; i < ar_size; i++) {
5760       for (j=Im_1; j <= Im_2; j++) ref_ar[i] += SAR(j)[i] ;
5761    }
5762    m = Im_2 - Im_1 + 1;
5763    for (i=0; i < ar_size; i++) ref_ar[i] = ref_ar[i] / m;
5764 
5765    XUnmapWindow(theDisp,  key[kIR1].wid);
5766    XUnmapWindow(theDisp,  key[kIR2].wid);
5767    XMapWindow  (theDisp,  key[kNRM].wid);
5768 
5769    diff_im = fim_dif = 1;
5770    im1_done = 0;
5771    old_im = -1;            /* to avoid faster reload of old data */
5772    Put_image(Im_Nr);
5773    redraw_graph();
5774    DrawSubWindow();
5775 /*
5776    DrawTopWindow();
5777 */
5778    return 0;
5779 }
5780 
5781 /* ------------- */
5782    int
Im_help(ikey)5783    Im_help(ikey)
5784    int ikey;
5785 /* ------------- */
5786 {
5787    The_Help(0);
5788    return 0;
5789 }
5790 
5791 /* ------------ */
5792    void
draw_frame()5793    draw_frame()
5794 /* ------------ */
5795 {
5796    register int i, yyy;
5797                                /* draw frame */
5798    line_color("black");
5799    for (i=0; i <= maty; i++) {
5800      yyy = mdy1+i*gy;
5801      if ( yyy > gy_max + GB_DLY ) yyy = gy_max + GB_DLY;
5802      plotx(mdx1       , yyy, 0);
5803      plotx(mdx1+matx*gx, yyy, 1);
5804    }
5805    for (i=0;i<=matx;i++) {
5806      plotx(mdx1+i*gx,mdy1       , 0);
5807      plotx(mdx1+i*gx,mdy1+maty*gy, 1);
5808    }
5809 }
5810 
5811 /* --------------------- */	/* Reload pixmap pxWind to GWindow */
graphic_store()5812    void graphic_store()
5813 /* --------------------- */
5814 {
5815    XSetWindowBackgroundPixmap(theDisp, GWindow, pxWind);
5816    XClearWindow(theDisp, GWindow);
5817    XFlush(theDisp);
5818 }
5819 
5820 /* ------------------- */	/* It plots line to point (x,y) for mod = 1 */
plotx(x,y,mod)5821    void plotx(x,y,mod)		/* or moves to this point for mod = 0.      */
5822    int x, y, mod;               /* All into the pxWind.                     */
5823 /* ------------------- */
5824 {
5825    int	iy = idY - y;
5826 
5827    if(mod == 0) { x00 = x; y00 = iy; }
5828    if(mod == 1) {
5829      XDrawLine(theDisp, pxWind, theGC, x00, y00, x, iy);
5830      x00 = x;	y00 = iy;
5831    }
5832 }
5833 
5834 /* --------------------- */	/* Plot text in pxWind at x,y position */
plx_txt(x,y,str)5835    void plx_txt(x,y,str)        /*  relative to lower left corner (!). */
5836    int  x, y;
5837    char *str;
5838 /* --------------------- */
5839 {
5840    int	iy = idY - y, n = strlen(str);;
5841    XDrawString(theDisp, pxWind, txtGC, x, iy, str, n);
5842 }
5843 
5844 /* -------------------------- */ /* Plot text in any window w at x, y */
plx_TXT(w,x,y,str)5845    void plx_TXT(w, x, y, str)    /* relative to lower left corner (!)   */
5846    Window w;
5847    int  x, y;
5848    char *str;
5849 /* -------------------------- */
5850 {
5851    Window r;
5852    int x0, y0;
5853    u_int  width, height, bw, dp;
5854 
5855    if (!XGetGeometry(theDisp, w, &r, &x0, &y0, &width, &height, &bw, &dp)) {
5856       printf("\n Problem in plx_TXT() with XGetGeometry\n");
5857       exit(10);
5858    }
5859    else
5860       XDrawString(theDisp, w, txtGC, x, height - y, str, strlen(str));
5861 }
5862 
5863 /* -------------------------- */ /* Plot text in subWindow  at x, y */
subW_TXT(x,y,str)5864    void subW_TXT(x, y, str)      /* relative to lower left corner (!) */
5865    int  x, y;
5866    char *str;
5867 /* -------------------------- */
5868 {
5869    XDrawString(theDisp, subWindow, txtGC, x, sub_W_y - y, str, strlen(str));
5870 }
5871 
5872 /* ----------------------- */	/* erase to background color */
5873    void
erase_graph()5874    erase_graph()        /*   */
5875 /* ----------------------- */
5876 {
5877    line_color("white");
5878    XFillRectangle(theDisp, pxWind, theGC, 0, 0, idX, idY);
5879 }
5880 
5881 /* ----------------------- */	/* redraw entire graph */
5882    void
redraw_graph()5883    redraw_graph()
5884 /* ----------------------- */
5885 {
5886    erase_graph();
5887    draw_marker();
5888    draw_frame();
5889    plot_line();
5890                                       /* draw min & max values in GWindow */
5891    sprintf(strp, "%05d", pmax[xc][yc]);
5892    plx_txt(xspace, GB_DLY + gy_max - mytxt, strp);
5893    sprintf(strp, "%05d", pmin[xc][yc]);
5894    plx_txt(xspace, GB_DLY + 5, strp);
5895 
5896    graphic_store();
5897 }
5898 
5899 /* -------------------- */     /* Change color for plotting */
line_color(col)5900    void line_color(col)        /* col - named color         */
5901    char *col;
5902 /* -------------------- */
5903 {
5904    XColor  any_col, rgb_col;
5905    char old_color[64] = "RW Cox" ;
5906 
5907    if( strcmp(col,old_color) == 0 ) return ;
5908 
5909    if (!(XAllocNamedColor(theDisp, CMap, col, &any_col, &rgb_col)))
5910       FatalError ("XAllocNamedColor problem. AJ");
5911    XSetForeground(theDisp, theGC, any_col.pixel);
5912 
5913    strcpy( old_color , col ) ;
5914 }
5915 
5916 /* -------------------- */     /* Change color for plotting */
txt_color(col)5917    void txt_color(col)         /* col - named color         */
5918    char *col;
5919 /* -------------------- */
5920 {
5921    XColor  any_col, rgb_col;
5922 
5923    if (!(XAllocNamedColor(theDisp, CMap, col, &any_col, &rgb_col)))
5924       FatalError ("XAllocNamedColor problem for text. AJ");
5925    XSetForeground(theDisp, txtGC, any_col.pixel);
5926 }
5927 
5928 /* ----------------------- */
5929    void
FatalError(identifier)5930    FatalError (identifier)
5931    char *identifier;
5932 /* ----------------------- */
5933 {
5934    fprintf(stderr, "%s: %s\a\n",ProgramName, identifier);
5935    exit(-1);
5936 }
5937 
5938 /* ----------------------------------- */
5939    void
CreateGraphWindow(argv,argc)5940    CreateGraphWindow(argv, argc)
5941    int  argc;
5942    char *argv[];
5943 /* ----------------------------------- */
5944 {
5945    XClassHint		class;
5946    XSetWindowAttributes attr;
5947    unsigned int		attrmask;
5948    XSizeHints		hints;
5949    int 			x = 0, y = 0;
5950 
5951 
5952    class.res_name  = "Graph";
5953    class.res_class = "Graph";
5954 
5955    hints.width = idX;         hints.height = idY;
5956    hints.max_width = idX;     hints.max_height = idY;
5957    hints.flags = PMaxSize;
5958 
5959    hints.min_width = idX;     hints.min_height = idY;
5960    hints.flags |= PMinSize;
5961 
5962    attr.background_pixel = bcol;
5963    attr.border_pixel     = fcol;
5964    attrmask = CWBackPixel | CWBorderPixel;
5965 
5966    GWindow = XCreateWindow(theDisp, rootW, x, y, idX, idY, 2,
5967 	CopyFromParent, CopyFromParent, CopyFromParent, attrmask, &attr);
5968 
5969    if (!GWindow)
5970       FatalError("Can't open window (are X11 windows running ?). AJ");
5971 
5972    XSetClassHint(theDisp, GWindow, &class);
5973    XSetStandardProperties(theDisp, GWindow, G_name, I_name, None,
5974 			  argv, argc, &hints);
5975 }
5976 
5977 /* ---------------------------- */
5978    void
Allow_smaller_gr(argc,argv)5979    Allow_smaller_gr(argc, argv)
5980    int  argc;
5981    char *argv[];
5982 /* ---------------------------- */
5983 {
5984    XSizeHints           hints;
5985 
5986    hints.min_height = 150;
5987    hints.min_width = 200;
5988    hints.flags = PMinSize;
5989 
5990    hints.max_height = DisplayHeight(theDisp, theScreen);
5991    hints.max_width  = DisplayWidth(theDisp, theScreen);
5992 
5993    hints.flags |= PMaxSize;
5994    XSetStandardProperties(theDisp, GWindow, G_name, I_name, None,
5995                           argv, argc, &hints);
5996 }
5997 
5998 /* -------------- */     /* discard events x (of ev) to stop faster */
5999    void
discard(x,ev)6000    discard(x, ev)
6001    int x;
6002    XEvent *ev;
6003 /* -------------- */
6004 {
6005    XSync(theDisp,False) ;
6006    while ( XCheckWindowEvent(theDisp, theWindow, x, ev) ) ;
6007    while ( XCheckWindowEvent(theDisp,   GWindow, x, ev) ) ;
6008 }
6009 
6010 /* ------------------------ */
6011    void
discard_Key(keyW,x,ev)6012    discard_Key(keyW, x, ev)
6013    int    x;
6014    XEvent *ev;
6015    Window keyW;
6016 /* ------------------------ */
6017 {
6018    while ( XCheckWindowEvent(theDisp, keyW, x, ev) ) ;
6019 }
6020 
6021 /* -------------------- */
6022    void
Track_Cursor(mx,my)6023    Track_Cursor(mx, my)
6024    int mx, my;
6025 /* -------------------- */
6026 {
6027    Window       rW, cW;
6028    u_int        key;
6029    int          x, y, rx, ry;
6030 
6031    while (XQueryPointer(theDisp, theWindow, &rW, &cW,
6032                                 &rx, &ry, &x, &y, &key)) {
6033       if ( !(key & Button1Mask) ) break;    /* button released */
6034 
6035       if ( mx != x || my != y ) {   /* this marker was moved */
6036          xpoint = Mltx[x]/x_mag;
6037          ypoint = Mlty[y]/x_mag;
6038          DrawSubWindow();
6039       }
6040       mx = x;
6041       my = y;
6042    }
6043 }
6044 /* -------------- */
6045    void
Vpointer(x,y)6046    Vpointer(x, y)
6047    int x, y;
6048 /* -------------- */
6049 {
6050    XPoint a[3];
6051                                  /* fill pattern is shifted by 1 pixel => -1 */
6052    a[0].x = x-1;    a[0].y = y-1;
6053    a[1].x = x-6;    a[1].y = y+10;
6054    a[2].x = x+4;    a[2].y = y+10;
6055 
6056    line_color("red");
6057    XFillPolygon(theDisp, subWindow, theGC, a, 3, Convex, CoordModeOrigin);
6058 }
6059 
6060 /* -------------- */
6061    void
Cpointer(x,y)6062    Cpointer(x, y )
6063    int x, y;
6064 /* -------------- */
6065 {
6066    int  i;
6067    XPoint a[12];
6068 
6069    for (i=0; i < 12; i++) {
6070       a[i].x = sm_cir[i].x + x;
6071       a[i].y = sm_cir[i].y + y;
6072    }
6073 
6074    line_color("red");
6075    XDrawPoints(theDisp, GWindow, theGC, a, 12, CoordModeOrigin);
6076 }
6077 
6078 /* -------------- */
6079    void
Cpointer_PIXWIN(x,y,color)6080    Cpointer_PIXWIN(x, y,color )
6081    int x, y;
6082    char * color ;
6083 /* -------------- */
6084 {
6085    int  i;
6086    XPoint a[12];
6087 
6088    for (i=0; i < 12; i++) {
6089       a[i].x = sm_cir[i].x + x;
6090       a[i].y = sm_cir[i].y + y;
6091    }
6092 
6093    line_color(color);
6094    XDrawPoints(theDisp, pxWind, theGC, a, 12, CoordModeOrigin);
6095 }
6096 
6097 /* ---------------- */ /* tracks continuousely v pointer and sets image nr */
6098    void
Track_Vpointer()6099    Track_Vpointer()
6100 /* ---------------- */
6101 {
6102    int          Im_Old, im, c_im;
6103    Window       rW, cW;
6104    u_int        key;
6105    int          x, y, rx, ry;
6106    int          aaa = avr_grp, ddd = diff_im, redr;
6107 
6108    im = Im_Old = Im_Nr;
6109 
6110    New_Cursor(theDisp, subWindow, XC_left_ptr, "red", "white");
6111 
6112    while (XQueryPointer(theDisp, subWindow, &rW, &cW,
6113                                 &rx, &ry, &x, &y, &key)) {
6114       if ( !(key & Button1Mask) ) break;    /* button released */
6115 
6116       if ( v_point_x != x ) {   /* the marker was moved */
6117 
6118          c_im = (min(gx, max(0, x - xorigin[xc][yc]))*npoints) / gx;
6119          if ( c_im < 0 )       c_im = 0;
6120          if ( c_im > npoints - Av_length ) c_im = npoints - Av_length;
6121          if ( im != c_im ) {
6122             Im_Nr = c_im;
6123             XClearWindow(theDisp, GWindow);
6124             DrawSubWindow();
6125          }
6126          im = c_im;
6127       }
6128    }
6129    v_point_x = xorigin[xc][yc] + Im_Nr*gx/(npoints-1);
6130 
6131    if ( Im_Nr != Im_Old ) {
6132       diff_im = fim_dif;
6133       avr_grp = fim_avr;
6134       Put_image(Im_Nr);
6135       redr =  avr_grp * 4 + (aaa - avr_grp) *2 + ddd - diff_im;
6136       if ( redr ) {
6137          old_im = -1;    /* to avoid faster reload of old data */
6138          redraw_graph();
6139          DrawTopWindow();
6140          DrawSubWindow();
6141       }
6142    }
6143 
6144    New_Cursor(theDisp, subWindow, XC_left_ptr, "blue", "yellow");
6145 }
6146 
6147 /* ------------------ */
is_file(fname)6148    int is_file(fname)
6149    char  *fname;
6150 /* ------------------ */
6151 {
6152    FILE          *fp;
6153 
6154    if ( (fp = fopen(fname, "r")) != NULL ) {    /* return = 1 if file exist */
6155       fclose(fp);
6156       return(1);
6157    }
6158    else
6159       return(0);
6160 }
6161 
6162 /* ----------------------------- */   /* write plot to file  */
print_plot(ask_file)6163    void print_plot(ask_file)
6164    int ask_file ;
6165 /* ----------------------------- */
6166 {
6167    int  i, x, y;
6168    static char noask_suffix[40] = "\0" ;
6169 
6170    if( ask_file ){
6171       if ( txtW_ON ) {
6172          XBell(theDisp, 100); return;
6173       }
6174       txtW_ON = 1;
6175 
6176       x = 50 + GL_DLX;
6177       y = 50 + GT_DLY;
6178 
6179       strp[0] = ASC_NUL;
6180       take_file_name(theDisp, GWindow , CMap, txtGC, mfinfo, x, y, strp, 41,
6181                      "Enter output plot name:", 1 );
6182       txtW_ON = 0 ;
6183 
6184    } else {
6185 
6186      if( noask_suffix[0] == '\0' ){
6187        if ( txtW_ON ) {
6188           XBell(theDisp, 100); return;
6189        }
6190        txtW_ON = 1;
6191 
6192        x = 50 + GL_DLX;
6193        y = 50 + GT_DLY;
6194 
6195        strp[0] = ASC_NUL;
6196        take_file_name(theDisp, GWindow , CMap, txtGC, mfinfo, x, y, strp, 41,
6197                      "Enter suffix for plot filenames:" , 0 );
6198        txtW_ON = 0 ;
6199 
6200        i = strlen(strp) ;
6201        if( i <= 0 || i >= 38 ){
6202           XBell(theDisp, 100); return;
6203        }
6204 
6205        strncpy( noask_suffix , strp , 40 ) ;
6206      }
6207 
6208      sprintf( strp , "%03d_%03d%s" ,  xpoint,ypoint,noask_suffix ) ;
6209    }
6210 
6211    if ( strp[0] != ASC_NUL ) {
6212       sprintf(plotbuf,"%d\n", val[xc][yc][0]);
6213       for (i=1; i < npoints; i++) {
6214           sprintf(fnum,"%d\n", val[xc][yc][i]);
6215           strcat(plotbuf, fnum);
6216       }
6217 
6218       isize = strlen(plotbuf);
6219       i = WRite_iqm(strp, &isize, plotbuf);
6220       if ( i != 0 ){
6221          XBell(theDisp, 100);
6222       } else {
6223          fprintf(stderr,"*** wrote plot file %s\n",strp) ;
6224       }
6225    }
6226 
6227    txtW_ON = 0;
6228 }
6229 
6230 /* --------------------- */
save_all_images()6231    int save_all_images()
6232 /* --------------------- */
6233 {
6234    int  i, x, y;
6235 
6236    if ( txtW_ON ) {
6237       XBell(theDisp, 100); return(2);
6238    }
6239    txtW_ON = 1;
6240 
6241    x = 50 + GL_DLX;
6242    y = 50 + GT_DLY;
6243 
6244    strp[0] = ASC_NUL ;
6245    take_file_name(theDisp, GWindow , CMap, txtGC, mfinfo, x, y, strp, 45,
6246                   "Enter output root name:", 0);
6247    im_f = min(3, dec_indx(npoints)-1);  /* 2d index in formt[][] */
6248 
6249 try_again:
6250    if ( strp[0] != ASC_NUL ) {
6251       /* test for first file */
6252       sprintf(strF, formt[0][im_f], strp, 1);
6253       if ( is_file(strF) ) {
6254          strp[0] = ASC_NUL;
6255          sprintf (strT, "File exist: %s", strF);
6256          take_file_name(theDisp, GWindow , CMap, txtGC, mfinfo, x, y, strp, 50,
6257                   strT, 0);
6258          goto try_again;
6259       }
6260       for (i=0; i < npoints; i++) {
6261          sprintf(strF, formt[0][im_f], strp, i+1);
6262          /* we have already decided whether to swap */
6263          if ( swap_bytes && allim[i]->kind == MRI_short ) {
6264            swap_2(MRI_SHORT_PTR(allim[i]), allim[i]->nx*allim[i]->ny*2);
6265          }
6266          else if ( swap_bytes && allim[i]->kind == MRI_float ) {
6267            swap_4(MRI_FLOAT_PTR(allim[i]), allim[i]->nx*allim[i]->ny*4);
6268          }
6269 
6270          mri_write(strF, allim[i]) ;
6271 
6272          if ( swap_bytes && allim[i]->kind == MRI_short ) {
6273            swap_2(MRI_SHORT_PTR(allim[i]), allim[i]->nx*allim[i]->ny*2);
6274          }
6275          else if ( swap_bytes && allim[i]->kind == MRI_float ) {
6276            swap_4(MRI_FLOAT_PTR(allim[i]), allim[i]->nx*allim[i]->ny*4);
6277          }
6278       }
6279    }
6280 
6281    txtW_ON = 0;
6282    return(0);
6283 }
6284 
6285 /* -------------------- save not normalized average image - called by 'X' */
save_avr_array()6286    int save_avr_array()
6287 /* -------------------- */
6288 {
6289    int  i, x, y;
6290 
6291    if ( txtW_ON ) {
6292       XBell(theDisp, 100); return(2);
6293    }
6294    txtW_ON = 1;
6295 
6296    x = 50 + GL_DLX;
6297    y = 50 + GT_DLY;
6298 
6299    strp[0] = ASC_NUL ;
6300    take_file_name(theDisp, GWindow , CMap, txtGC, mfinfo, x, y, strp, 41,
6301                   "Enter output image name:" , 1 );
6302    for( i=0 ; i < IM_ARR ; i++ ) a_rot[i] = tmp_ar[i];
6303    for( i=0 ; i < IM_ARR ; i++ ) tmp_ar[i] = av_ar[i];
6304    if ( strp[0] != ASC_NUL ) {
6305       mri_write( strp , im_tmp_ar ) ;
6306    }
6307    for( i=0 ; i < IM_ARR ; i++ ) tmp_ar[i] = a_rot[i];
6308 
6309    txtW_ON = 0;
6310    return(0);
6311 }
6312 
6313 /* ----------------- */
save_act_im()6314    int save_act_im()
6315 /* ----------------- */
6316 {
6317    int  x, y;
6318 
6319    if ( txtW_ON ) {
6320       XBell(theDisp, 100); return(2);
6321    }
6322    txtW_ON = 1;
6323 
6324 /* AJJ  OK in relation to the root window
6325    XGetWindowAttributes(theDisp, theWindow, &wat);
6326    XTranslateCoordinates(theDisp, theWindow, wat.root, -wat.border_width,
6327                         -wat.border_width, &x, &y, &ww);
6328    x += eWIDE/2;
6329    y += eHIGH/2;
6330 
6331    strp[0] = ASC_NUL ;
6332    take_file_name(theDisp, rootW, CMap, txtGC, mfinfo, x, y, strp, 40,
6333                   "Enter image name:" ,  1 );
6334 */
6335 
6336    x = 50 + GL_DLX;
6337    y = 50 + GT_DLY;
6338 
6339    strp[0] = ASC_NUL ;
6340    take_file_name(theDisp, GWindow , CMap, txtGC, mfinfo, x, y, strp, 41,
6341                   "Enter output image name:" , 1 );
6342    if ( strp[0] != ASC_NUL ) {
6343       /* we have already decided on swapping     27 Aug 2004 [rickr] */
6344 
6345       if ( swap_bytes && im_tmp_ar->kind == MRI_short ) {
6346         swap_2(MRI_SHORT_PTR(im_tmp_ar), im_tmp_ar->nx*im_tmp_ar->ny*2);
6347       }
6348       else if ( swap_bytes && im_tmp_ar->kind == MRI_float ) {
6349         swap_4(MRI_FLOAT_PTR(im_tmp_ar), im_tmp_ar->nx*im_tmp_ar->ny*4);
6350       }
6351 
6352       mri_write( strp , im_tmp_ar ) ;
6353 
6354       if ( swap_bytes && im_tmp_ar->kind == MRI_short ) {
6355         swap_2(MRI_SHORT_PTR(im_tmp_ar), im_tmp_ar->nx*im_tmp_ar->ny*2);
6356       }
6357       else if ( swap_bytes && im_tmp_ar->kind == MRI_float ) {
6358         swap_4(MRI_FLOAT_PTR(im_tmp_ar), im_tmp_ar->nx*im_tmp_ar->ny*4);
6359       }
6360    }
6361 
6362    txtW_ON = 0;
6363    return(0);
6364 }
6365 
6366 /* popup window which take a file name of max length str_l */
6367 /* --------------------------------------- return name of file in name */
6368    void
take_file_name(theDisp,topW,CMap,txtGC,finf,x,y,name,str_l,text,check)6369    take_file_name(theDisp, topW, CMap, txtGC, finf, x, y, name, str_l, text, check)
6370    Display     *theDisp;
6371    Window      topW;                    /* top window of this popup one */
6372    Colormap    CMap;
6373    GC          txtGC;
6374    XFontStruct *finf;
6375    int         x, y;                    /* relative position */
6376    char *name, *text;                   /* name - file name, max str_l chars */
6377    int  str_l;                          /* text - window's header */
6378    int  check ;                         /* to check if name exists already? */
6379 /* --------------------------------------- */
6380 {
6381    int    w_l1, w_h1, w_l2, w_h2, h_txt, expose = 0, name_OK = 0, length;
6382    int    x_txt, y_txt, x_l2, y_l2, error = 0;
6383    int    eee[2];
6384    char   *errr = "File exist:", *DT = "_";
6385 
6386    XEvent ev;
6387    XColor             any_col, rgb_col;
6388    unsigned long      Border, back1, back2; // long is OK here AJJ
6389    Window             txtWindow1, txtWindow2;
6390    XSizeHints         hints;
6391 
6392    eee[0] = eee[1] = 0;
6393 
6394    if (!(XAllocNamedColor(theDisp, CMap, "red", &any_col, &rgb_col)))
6395       FatalError ("XAllocNamedColor problem. AJ in save_act_im()");
6396    Border = any_col.pixel;
6397    if (!(XAllocNamedColor(theDisp, CMap, "yellow", &any_col, &rgb_col)))
6398       FatalError ("XAllocNamedColor problem. AJ in save_act_im()");
6399    back1= any_col.pixel;
6400    if (!(XAllocNamedColor(theDisp, CMap, "white", &any_col, &rgb_col)))
6401       FatalError ("XAllocNamedColor problem. AJ in save_act_im()");
6402    back2= any_col.pixel;
6403 
6404    hints.flags = USPosition;
6405    hints.x = x;
6406    hints.y = y;
6407 
6408    h_txt =  finf->max_bounds.ascent + finf->max_bounds.descent;
6409    w_l1 = (str_l - 1) * finf->max_bounds.width + 30;
6410    w_h1 = 3 * h_txt + 18;
6411    x_l2 = 10;
6412    y_l2 = 2 * h_txt + 5;
6413    w_l2 = w_l1 - 20;
6414    w_h2 = h_txt + 8;
6415    x_txt = 5;
6416    y_txt = h_txt;
6417 
6418    txtWindow1 =  XCreateSimpleWindow(theDisp, topW, x, y, w_l1, w_h1, 1,
6419                                      Border, back1);
6420    XSelectInput(theDisp, txtWindow1, ExposureMask);
6421    XSetStandardProperties(theDisp, txtWindow1 , "Text", "Text", None,
6422                           NULL, 0, &hints);
6423    txtWindow2 =  XCreateSimpleWindow(theDisp, txtWindow1, x_l2, y_l2,
6424                             w_l2, w_h2, 1, Border, back2);
6425    XSelectInput(theDisp, txtWindow2, ExposureMask | KeyPressMask);
6426    New_Cursor(theDisp, txtWindow1, XC_left_ptr, "blue", "white");
6427    New_Cursor(theDisp, txtWindow2, XC_xterm, "blue", "white");
6428    XMapWindow(theDisp, txtWindow1);
6429    XMapWindow(theDisp, txtWindow2);
6430 
6431    while ( !expose ) {                /* wait for expose */
6432       Window wind;
6433       XNextEvent(theDisp, &ev);
6434       switch (ev.type) {
6435          case Expose: {
6436             XExposeEvent *e = (XExposeEvent *) &ev;
6437             wind = e->window;
6438             if (wind ==  txtWindow1) eee[0] = 1;
6439             if (wind ==  txtWindow2) eee[1] = 1;
6440             expose = eee[0] * eee[1];
6441          }
6442          default:                /* ignore unexpected events */
6443             break;
6444       }
6445    } /* end of while( !expose ) */
6446 
6447    txt_color("red");
6448    XDrawString(theDisp, txtWindow1, txtGC, 9, h_txt + 3 ,
6449                text, strlen(text));
6450    strncat(name, DT, 1);
6451    txt_color("blue");
6452    XDrawString(theDisp, txtWindow2, txtGC, x_txt, y_txt,
6453                name, strlen(name));
6454 
6455    txt_color("black");
6456 
6457    while ( !name_OK ) {                /* wait for file name */
6458       Window wind;
6459       XNextEvent(theDisp, &ev);
6460       switch (ev.type) {
6461          case Expose: {
6462             XExposeEvent *e = (XExposeEvent *) &ev;
6463 
6464             wind = e->window;
6465             if (wind ==  txtWindow1) {
6466                txt_color("red");
6467                XDrawString(theDisp, txtWindow1, txtGC, 30, h_txt + 3 ,
6468                            text, strlen(text));
6469                txt_color("black");
6470             }
6471             if (wind ==  txtWindow2) {
6472                txt_color("blue");
6473                XDrawString(theDisp, txtWindow2, txtGC, x_txt, y_txt,
6474                            name, strlen(name));
6475                txt_color("black");
6476             }
6477          }
6478          case KeyPress: {
6479             XKeyEvent *key_event = (XKeyEvent *) &ev;
6480             u_char      buf[128];
6481             KeySym    ks;
6482             XComposeStatus status;
6483 
6484             wind = key_event->window;
6485             if (wind ==  txtWindow2) {
6486                if (error) {
6487                   XClearWindow(theDisp, txtWindow1);
6488                   txt_color("red");
6489                   XDrawString(theDisp, txtWindow1, txtGC, 25, h_txt + 3 ,
6490                               text, strlen(text));
6491                   txt_color("black");
6492                   error = 0;
6493                }
6494                buf[0] = 0;
6495                XLookupString(key_event, (char *)buf, 128, &ks, &status);
6496                if ( (ks == XK_Return)   ||
6497                     (ks == XK_Linefeed) ) {
6498                   length = strlen(name);
6499                   name[length-1] = ASC_NUL;
6500                   if ( name[0] == ASC_NUL ) name_OK = 1;
6501                   else if ( check && is_file(name) ) {
6502                      XClearWindow(theDisp, txtWindow1);
6503                      txt_color("red");
6504                      XDrawString(theDisp, txtWindow1, txtGC, 10, h_txt ,
6505                            errr, strlen(errr));
6506                      XDrawString(theDisp, txtWindow1, txtGC, 15, 2*h_txt ,
6507                            name, strlen(name));
6508                      txt_color("black");
6509                      name[0] = ASC_NUL;
6510                      strncat(name, DT, 1);
6511                      XBell(theDisp, 100);
6512                      error = 1;
6513                   }
6514                   else
6515                      name_OK = 1;
6516                }
6517                else if ( ((ks >= XK_plus) && (ks <= XK_9)) ||
6518                          ((ks >= XK_A) && (ks <= XK_Z))  ||
6519                          ((ks >= XK_asciicircum) && (ks <= XK_z)) ||
6520                           (ks == XK_asciitilde)                   ||
6521                           (ks == XK_numbersign)                   ||
6522                           (ks == XK_colon     )                   ||
6523                           (ks == XK_at        )                   ||
6524                           (ks == XK_underscore)                   ||
6525                           (ks == XK_exclam)     ) {
6526                   if ( (length = strlen(name)) + 1 > str_l ) {
6527                      name[length-1] = ' ';
6528                      XBell(theDisp, 100);
6529                   }
6530                   else if ( ((buf[0] >= 43) && (buf[0] <= 57)) ||
6531                             ((buf[0] >= 65) && (buf[0] <= 90)) ||
6532                             ((buf[0] >= 94) && (buf[0] <= 122))||
6533                              (buf[0] == 126)                   ||
6534                              (buf[0] == '!') ) {
6535                      name[length - 1] = ASC_NUL;
6536                      strncat(name, (char *)buf, 1);
6537                      strncat(name, DT, 1);
6538                   }
6539                }
6540                else if ( ((ks >= XK_Shift_L) && (ks <= XK_Hyper_R)) ||
6541                          ((ks >= XK_F1) && (ks <= XK_F35)) ||
6542                          ((ks >= XK_KP_0) && (ks <= XK_KP_9)) )
6543                      ;     /* do nothing */
6544                else if ((ks == XK_BackSpace) || (ks == XK_Delete)) {
6545                   if ( (length = strlen(name)) > 1 ) {
6546                      name[length - 2] = ASC_NUL;
6547                      strncat(name, DT, 1);
6548                   }
6549                   else
6550                      XBell(theDisp, 100);
6551                }
6552                else
6553                   XBell(theDisp, 100);
6554             }
6555             XClearWindow(theDisp, txtWindow2);
6556             txt_color("blue");
6557             XDrawString(theDisp, txtWindow2, txtGC, x_txt, y_txt,
6558                         name, strlen(name));
6559             txt_color("black");
6560          }
6561          default:                /* ignore unexpected events */
6562             break;
6563       }
6564 
6565    } /* end of while( !name_OK ) */
6566 
6567    txt_color("black");
6568    XDestroyWindow(theDisp, txtWindow1);
6569 }
6570 
6571 /**************************************************************************/
6572 /**************************************************************************/
6573 /**************************************************************************/
6574 
6575 #define MAX_NREF (MAX_NUMORT+MAX_POLORT+99)
6576 
6577 
RWC_setup_fims(imflag)6578 void RWC_setup_fims( imflag )
6579    int imflag ;
6580 {
6581    int kim , nref ;
6582    float current_refs[MAX_NREF] ;
6583    float *id ;
6584    float *pc , *alp ;
6585    thresh_result thr ;
6586 
6587    float        alp_max , alp_thr[MAX_FIM_COLORS] ;
6588    register int jj , ii , nvox ;
6589 
6590    static MRI_IMAGE * thrim = NULL ;
6591    static short *     thrar = NULL ;
6592    static short       imthr ;
6593 
6594    MRI_IMAGE * flim = NULL;
6595    float     * flar = NULL;
6596    double      scl = 0., dkim , pval ;
6597    int         make_thrim , good ;
6598 
6599    static MRI_IMARR * DFILT_rim  = NULL ;
6600 
6601    /*** check RWC_ideal for legality ***/
6602 
6603    if( RWC_ideal == NULL ){
6604       RWC_do_overfim = 0 ;
6605       if( RWC_imover != NULL ) { free(RWC_imover) ; RWC_imover = NULL ; }
6606       return ;
6607    }
6608 
6609    id = RWC_ideal->ts ;
6610 
6611    if( RWC_ideal->len < npoints ){
6612       fprintf(stderr,
6613               "\n*** reference vector time series file %s too short!\n",
6614               RWC_ideal->fname ) ;
6615 
6616       RWC_do_overfim = 0 ;
6617       RWC_free_time_series( RWC_ideal ) ; RWC_ideal = NULL ;
6618       if( RWC_imover != NULL ) { free(RWC_imover) ; RWC_imover = NULL ; }
6619       XBell(theDisp,100) ; return ;
6620    }
6621 
6622    for( ii=0 ; ii < RWC_numort ; ii++ ){
6623       if( RWC_ort[ii] == NULL || RWC_ort[ii]->len < npoints ){
6624          fprintf( stderr ,
6625                   "\n*** ort vector time series file %s too short!\n",
6626                   RWC_ort[ii]->fname ) ;
6627          RWC_do_overfim = 0 ;
6628          if( RWC_imover != NULL ) { free(RWC_imover) ; RWC_imover = NULL ; }
6629          XBell(theDisp,100) ; return ;
6630       }
6631    }
6632 
6633    /*** miscellaneous startup ***/
6634 
6635    if( RWC_fim_colors == 0 ) RWC_init_fim_colors() ;
6636 
6637    nref = RWC_numort + RWC_polort + 2 ;
6638 
6639    if( DFILT_code == DFILT_TIME ){
6640       nref += DFILT_NREF ;     /* number of refs from DFILT      */
6641    }
6642 
6643    if( LSQ_ref[0] == NULL ){
6644       for( ii=0 ; ii < MAX_TOTAL_REF ; ii++ )
6645          LSQ_ref[ii] = RWC_blank_time_series(NF_MAX) ;
6646    }
6647    LSQ_refcount = nref ;
6648 
6649    RWC_nxim = RWC_nyim = im_size ;  nvox = RWC_nxim * RWC_nyim ;
6650 
6651    RWC_refs   = new_references( nref ) ;
6652    RWC_voxcor = new_voxel_corr( RWC_nxim * RWC_nyim , nref ) ;
6653 
6654    if( RWC_pcim  != NULL ) mri_free( RWC_pcim ) ;
6655    if( RWC_alpim != NULL ) mri_free( RWC_alpim ) ;
6656 
6657    RWC_pcim  = mri_new( RWC_nxim , RWC_nyim , MRI_float ) ;
6658    RWC_alpim = mri_new( RWC_nxim , RWC_nyim , MRI_float ) ;
6659    pc        = mri_data_pointer( RWC_pcim ) ;
6660    alp       = mri_data_pointer( RWC_alpim ) ;
6661 
6662    if( RWC_refs == NULL || RWC_voxcor == NULL ){
6663       fprintf(stderr,"*** ==> malloc fail while fimming\a\n") ;
6664       mri_free( RWC_pcim )  ; RWC_pcim  = NULL ;
6665       mri_free( RWC_alpim ) ; RWC_alpim = NULL ;
6666       if( RWC_voxcor != NULL ) free_voxel_corr( RWC_voxcor ) ;
6667       if( RWC_refs   != NULL ) free_references( RWC_refs ) ;
6668       if( RWC_ideal  != NULL ) {RWC_free_time_series(RWC_ideal);RWC_ideal=NULL;}
6669       if( RWC_imover != NULL ) {free(RWC_imover) ; RWC_imover=NULL;}
6670       RWC_do_overfim = 0 ;
6671       return ;
6672    }
6673 
6674 /*** prepare to make thresholding image, if not already present ***/
6675 
6676    make_thrim = (thrim == NULL) ;
6677    if( make_thrim ){
6678       flim = mri_new( RWC_nxim , RWC_nyim , MRI_float ) ;
6679       flar = mri_data_pointer( flim ) ;
6680       scl  = 0.0 ;
6681       for( ii=0 ; ii < nvox ; ii++ ) flar[ii] = 0.0 ;
6682    }
6683 
6684 /*** find first "good" image and initialize DFILT, if needed ***/
6685 
6686 /*** put images thru the fim wringer ***/
6687 
6688    for( kim=0 ; kim < npoints ; kim++ ){
6689       good = fabs(id[kim]) < 33333.0 ;        /* check ideal and orts for OK */
6690       for( ii=0 ; ii < RWC_numort ; ii++ )
6691          good = good && ( fabs(RWC_ort[ii]->ts[kim]) < 33333.0 ) ;
6692 
6693       /** load the current_refs even if not good **/
6694 
6695       dkim = kim / ((double) npoints) ;
6696       pval = 1.0 ;
6697       for( ii=0 ; ii <= RWC_polort ; ii++ ){
6698          current_refs[ii] = pval ;
6699          pval            *= dkim ;
6700       }
6701 
6702       for( ii=0 ; ii < RWC_numort ; ii++ )
6703          current_refs[ii+RWC_polort+1] = RWC_ort[ii]->ts[kim] ;
6704 
6705       current_refs[nref-1] = id[kim] ;       /* load ideal as last ref */
6706 
6707       /** load LSQ_ref **/
6708 
6709       for( ii=0 ; ii < nref ; ii++ ){
6710          dkim = current_refs[ii] ;
6711          LSQ_ref[ii]->ts[kim] = (fabs(dkim) < 33333.0) ? dkim : 0.0 ;
6712       }
6713 
6714       /** process if all refs are good **/
6715 
6716       if( good ){
6717 	 nowim = SAR(kim) ;
6718          update_references( current_refs , RWC_refs ) ;
6719          update_voxel_corr( nowim , RWC_refs , RWC_voxcor ) ;
6720 
6721 	 if( make_thrim ){
6722 	    for( ii=0 ; ii < nvox ; ii++ ) flar[ii] += abs(nowim[ii]) ;
6723 	    scl++ ;  /* one more image */
6724          }
6725       }  /* end if(good) */
6726    } /* end for kim */
6727 
6728    DESTROY_IMARR( DFILT_rim ) ;
6729 
6730    /*** setup threshold on image intensity ***/
6731 
6732    if( make_thrim ){
6733       scl   = 1.0 / scl ;
6734       thrim = mri_to_short( scl , flim ) ;           /* average of abs */
6735       thrar = mri_data_pointer( thrim ) ;
6736       imthr = (short) ( 0.05 * mri_max( thrim ) ) ;  /* 5% threshold */
6737       mri_free( flim ) ;                             /* old junk */
6738    }
6739 
6740    /*** compute and threshold on correlation coefficient ***/
6741 
6742    get_pcor_thresh_coef( RWC_refs , RWC_voxcor ,
6743                          0.001 , 0.001 , pc , alp , &thr ) ;
6744 
6745    /*** compute least squares fit coefficients in each voxel ***/
6746 
6747    DESTROY_IMARR( LSQ_fitim ) ;
6748    INIT_IMARR( LSQ_fitim ) ;
6749    for( ii=0 ; ii < nref ; ii++ ){
6750       flim = mri_new( RWC_nxim , RWC_nyim , MRI_float ) ;
6751       ADDTO_IMARR(LSQ_fitim,flim) ;
6752       LSQ_fit[ii] = MRI_FLOAT_PTR(flim) ;
6753    }
6754    get_lsqfit( RWC_refs , RWC_voxcor , LSQ_fit ) ;
6755 
6756    if( RWC_imover != NULL ){  /* toss old overlay, if any */
6757       free(RWC_imover) ;
6758       RWC_imover = NULL ;
6759    }
6760 
6761 /*** threshold results on voxel data and fim results ***/
6762 
6763    alp_max = 0.0 ;
6764    for( ii=0 ; ii < nvox ; ii++ ){
6765       if( fabs(pc[ii]) >= RWC_pcthresh ){
6766          alp_max = (alp[ii]>0) ? MAX(alp_max, alp[ii])
6767                                : MAX(alp_max,-alp[ii]) ;
6768       }
6769    }
6770 
6771    if( alp_max > 0.0 ){
6772 
6773       RWC_imover = RWC_create_overlay( RWC_nxim , RWC_nyim ) ;
6774 
6775       for( ii=0 ; ii < RWC_fim_colors ; ii++ ){
6776          alp_thr[ii] = RWC_fim_thresh[ii] * alp_max ;
6777       }
6778 
6779    /*** loop over all voxels ***/
6780 
6781       for( ii=0 ; ii < nvox ; ii++ ){
6782 
6783          if( thrar[ii] >= imthr && fabs(pc[ii]) >= RWC_pcthresh ){
6784 
6785             if( alp[ii] >= alp_thr[0] ){  /* positive over threshold */
6786 
6787                for( jj=1 ; jj < RWC_fim_colors ; jj++ )  /* find place */
6788                   if( alp[ii] < alp_thr[jj] ) break ;
6789 
6790                RWC_imover[ii] = RWC_fim_colors_pos[jj-1] ;
6791 
6792             }
6793 
6794             else if( alp[ii] <= -alp_thr[0] ){  /* negative over threshold */
6795 
6796                for( jj=1 ; jj < RWC_fim_colors ; jj++ )  /* find place */
6797                   if( alp[ii] > -alp_thr[jj] ) break ;
6798 
6799                RWC_imover[ii] = RWC_fim_colors_neg[jj-1] ;
6800 
6801             }
6802          } /* end if nowim && pc */
6803      } /* end for ii (voxel loop) */
6804 
6805      pc[1]  = 1.0     ; pc[2]  = -1.0 ;
6806      alp[1] = alp_max ; alp[2] = -alp_max ;
6807 
6808      RWC_overhide = 0 ;
6809 
6810      if( imflag ){  /* display results */
6811 
6812         ii = Im_Nr ;
6813 
6814         mri_add_name( "correlation_image" , RWC_pcim ) ;
6815         add_extra_image( RWC_pcim ) ;
6816 
6817         mri_add_name( "fim_image" , RWC_alpim ) ;
6818         add_extra_image( RWC_alpim ) ;
6819 
6820         Im_Nr = ii ;
6821         Put_image( Im_Nr ) ;
6822      }
6823 
6824    } /* end if alp_max */
6825 
6826    free_voxel_corr( RWC_voxcor ) ; free_references( RWC_refs ) ;
6827 
6828    return ;
6829 }
6830 
6831 /****************************************************************************/
6832 
FIM_action(ikey)6833 int FIM_action(ikey)
6834   int ikey ;
6835 {
6836    int i ;
6837 #ifdef USE_MCW
6838    static int mcw_count = 0 ;
6839 #endif
6840 
6841    for( i=FIM_first_key ; i <= FIM_last_key ; i++ ){
6842       if( FIM_pressed ) XUnmapWindow(theDisp,  key[i].wid);  /* second press */
6843       else              XMapWindow  (theDisp,  key[i].wid);  /* first press */
6844    }
6845 
6846    if( FIM_pressed ){                  /* second press */
6847       FIM_pressed = 0 ;
6848       xtkeys[kFIM].st = key_kFIM_FIM ;
6849       DrawKey(kFIM) ;                  /* restore key label */
6850 
6851       if( RWC_do_overfim && FIM_modified ){
6852 #ifdef USE_MCW
6853          mcw_count++ ; Put_image(-1) ;  /* show the logo */
6854 #endif
6855          InvertKey(kFIM) ;
6856          XFlush(theDisp) ;
6857          RWC_setup_fims( 1 ) ;  /* 1 => display results */
6858          InvertKey(kFIM) ;
6859       }
6860 
6861       Put_image( Im_Nr ) ;
6862       DrawTopWindow() ;
6863       redraw_graph() ;
6864 
6865    } else {                            /* first press */
6866 
6867      FIM_pressed  = 1;
6868      FIM_modified = 0 ;
6869      xtkeys[kFIM].st = key_kFIM_GO ;
6870      DrawKey(kFIM) ;                  /* set key label to "GO" */
6871    }
6872    return 0;
6873 }
6874 
6875 /****************************************************************************/
6876 
FIM_selection(ikey)6877 int FIM_selection(ikey)
6878   int ikey ;
6879 {
6880    int x , y , ifim = ikey - FIM_first_key , ref_modified = 0 ;
6881    float fval ;
6882    char *cpt ;
6883    char stst[64] ;
6884    time_series *newts ;
6885 
6886    if ( txtW_ON || ikey < FIM_first_key || ikey > FIM_last_key ) {
6887       XBell(theDisp, 100); return 0;
6888    }
6889 
6890    if( FIM_selection_name[ifim] != NULL ){  /* if dialog box has a label */
6891       txtW_ON = 1;
6892 
6893       if( ifim != 1 ){
6894 	 strcpy(stst,FIM_selection_name[ifim]) ;
6895       } else {
6896               if( rot_direct == -1 ) strcpy(stst,"Reference ") ;
6897          else if( rot_direct ==  0 ) strcpy(stst,"Ort ") ;
6898          else                        strcpy(stst,"Useless ") ;
6899 	 strcat(stst,FIM_selection_name[ifim]) ;
6900       }
6901 
6902       x = 50 + GL_DLX;
6903       y = xtkeys[FIM_first_key].y ;
6904 
6905       strp[0] = ASC_NUL ;
6906       take_file_name(theDisp, GWindow , CMap, txtGC, mfinfo, x, y, strp, 41,
6907                      stst , 0 );
6908       txtW_ON = 0 ;
6909       if( strlen(strp) <= 0 ) return 0;
6910    }
6911 
6912    switch( ikey ){
6913 
6914       /*** set threshold ***/
6915 
6916       case kFI1:
6917          fval = strtod( strp , &cpt ) ;
6918          if( *cpt != ASC_NUL || fval < 0.0 || fval > 1.0 ){
6919             fprintf(stderr,
6920                     "\n*** Illegal correlation threshold %s!\n" , strp ) ;
6921             XBell(theDisp, 100); return 0;
6922          } else {
6923             RWC_pcthresh = fval ;
6924          }
6925       break ;  /* end of ikey=kFI1 */
6926 
6927      /*** set reference time series ***/
6928 
6929       case kFI2:
6930 
6931          /*** turn FIM off ***/
6932 
6933          if( strcmp(strp,"!nofim") == 0 ){
6934 
6935             RWC_do_overfim = 0 ;
6936             if( RWC_imover != NULL ) { free(RWC_imover) ; RWC_imover = NULL ; }
6937             if( RWC_ideal  != NULL ){
6938                RWC_free_time_series( RWC_ideal ) ;
6939                RWC_ideal = NULL ;
6940             }
6941 
6942          } else {
6943 
6944             newts = RWC_read_time_series( strp ) ;
6945             if( newts == NULL || newts->len < npoints ){
6946                fprintf(stderr,
6947                        "\n*** Illegal vector file %s!\n" , strp ) ;
6948                XBell(theDisp, 100); return 0;
6949             }
6950 
6951             if( rot_direct == -1 ){  /* left button */
6952                if( RWC_ideal != NULL ) RWC_free_time_series( RWC_ideal ) ;
6953                RWC_ideal      = newts ;
6954                RWC_do_overfim = 1 ;
6955 
6956             } else if( rot_direct == 0 ){ /* middle button */
6957                if( RWC_numort >= MAX_NUMORT ){ XBell(theDisp, 100); return 0; }
6958                RWC_ort[RWC_numort++] = newts ;
6959 
6960             } else { XBell(theDisp, 100); return 0; }
6961 
6962          }
6963          ref_modified      = 1 ;
6964 	 kFI3_refsum_count = -1 ;
6965       break ;  /* end of ikey=kFI2 */
6966 
6967       case kFI3:
6968          if( rot_direct == 1 ){  /* right button => change key */
6969 
6970             if( (rot_state & (ShiftMask | ControlMask)) == 0 ){
6971                kFI3_status = (kFI3_status+1) % (kFI3_NUM) ;       /* forward */
6972             } else {
6973                kFI3_status = (kFI3_status-1+kFI3_NUM) % (kFI3_NUM) ;/*backward*/
6974             }
6975             xtkeys[kFI3].st = key_kFI3[kFI3_status] ;
6976             DrawKey(kFI3) ;
6977             return 0;
6978          }  /* end of handling right button press */
6979 
6980          /*** perform actions based on status of key ***/
6981 
6982          switch( kFI3_status ){
6983 
6984             case -1:{
6985                int ii ;
6986 
6987                fprintf(stderr,"\a\n") ;
6988                fprintf(stderr,"*** Button 3 cycles between options  ***\n");
6989                fprintf(stderr,"*** [Shift+Button 3 cycles backwards ***\n");
6990                fprintf(stderr,"*** Buttons 1 and 2 choose options:  ***\n");
6991                fprintf(stderr,"***   for -+ options, Button 1 is -  ***\n");
6992                fprintf(stderr,"***                   Button 2 is +  ***\n");
6993                fprintf(stderr,"*** Keys available:\n") ;
6994 
6995                for( ii=0 ; ii < kFI3_NUM ; ii++ )
6996                   fprintf(stderr,"    %s %s\n" ,
6997                           key_kFI3[ii] , key_kFI3_help[ii] ) ;
6998 
6999             }
7000             /* fall through to default on purpose */
7001 
7002             default:{
7003                XBell(theDisp,100) ; return 0;
7004             }
7005 
7006          /*** use current pixel ***/
7007 
7008             case 0:
7009             case 1:{
7010                char * fake_name ;
7011                float * id ;
7012                int ii , addit ;
7013 
7014                fake_name = (char *) malloc( 24 ) ;
7015                if( fake_name == NULL ){
7016                   XBell(theDisp,100) ; return 0;
7017                }
7018 
7019                addit = (kFI3_status == 1) && ( RWC_ideal != NULL )
7020                                           && ( RWC_do_overfim )    ;
7021 
7022                if( !addit ){
7023                   RWC_free_time_series( RWC_ideal ) ;
7024                   RWC_ideal = RWC_blank_time_series( npoints ) ;
7025                }
7026 
7027                id = RWC_ideal->ts ;
7028 
7029 	       if( addit && kFI3_refsum_count < 0 ){
7030 		  for( ii=0 ; ii < npoints ; ii++ )
7031 		     if( fabs(id[ii]) < 33333.0 ) id[ii] *= 0.01 ;
7032 
7033                   kFI3_refsum_count = 1 ;
7034                }
7035 
7036                if( addit ){
7037                   for( ii=0 ; ii < npoints ; ii++ )
7038                                           id[ii] += 0.01*val[xc][yc][ii];
7039                   kFI3_refsum_count++ ;
7040                } else {
7041                   for( ii=0 ; ii < npoints ; ii++ )
7042                                           id[ii]  = 0.01*val[xc][yc][ii];
7043                   kFI3_refsum_count = 1 ;
7044                }
7045 
7046                if( addit ){
7047                   sprintf( fake_name , "%d:+PIX%d:%d" , kFI3_refsum_count,xpoint,ypoint ) ;
7048                } else {
7049                   sprintf( fake_name , "PIX%d:%d" , xpoint,ypoint ) ;
7050                }
7051                if( RWC_ideal->fname != NULL ) free( RWC_ideal->fname ) ;
7052                RWC_ideal->fname = fake_name ;
7053 
7054                RWC_do_overfim = 1 ;
7055                ref_modified   = 1 ;
7056             }
7057             break ;  /* end of status=0 or 1 */
7058 
7059             /*** median filter ***/
7060 
7061             case 2:{
7062                char * fake_name ;
7063                int flen ;
7064 
7065                if( RWC_ideal == NULL || !RWC_do_overfim ){
7066                   XBell(theDisp,100) ; return 0;
7067                }
7068 
7069                RWC_medfilt_time_series( RWC_ideal ) ;
7070 
7071                flen = 4 ;
7072                if( RWC_ideal->fname != NULL ) flen += strlen(RWC_ideal->fname) ;
7073 
7074                fake_name = (char *) malloc( flen ) ;
7075                if( fake_name != NULL ){
7076                   strcpy(fake_name,RWC_ideal->fname) ;
7077                   strcat(fake_name,"!m") ;
7078                   if( RWC_ideal->fname != NULL ) free( RWC_ideal->fname ) ;
7079                   RWC_ideal->fname = fake_name ;
7080                }
7081 
7082                ref_modified = 1 ;
7083             }
7084             break ;  /* end of status=2 */
7085 
7086             /*** modify threshold ***/
7087 
7088             case 3:{
7089 
7090                if( RWC_ideal == NULL || !RWC_do_overfim ){
7091                   XBell(theDisp,100) ; return 0;
7092                }
7093 
7094                if( rot_direct   == -1  ) RWC_pcthresh -= 0.05 ;
7095                if( rot_direct   ==  0  ) RWC_pcthresh += 0.05 ;
7096                if( RWC_pcthresh >= 1.0 ) RWC_pcthresh  = 0.99999 ;
7097                if( RWC_pcthresh <  0.0 ) RWC_pcthresh  = 0.0 ;
7098             }
7099             break ;  /* end of status=3 */
7100 
7101             /*** nofim ***/
7102 
7103             case 4:{
7104                RWC_do_overfim = 0 ;
7105                if( RWC_imover != NULL ) {free(RWC_imover); RWC_imover = NULL;}
7106                if( RWC_ideal != NULL ){
7107                   RWC_free_time_series( RWC_ideal ) ;
7108                   RWC_ideal = NULL ;
7109                }
7110                ref_modified = 1 ;
7111             }
7112             break ;  /* end of status=4 */
7113 
7114             /*** number of ref plots to show ***/
7115 
7116             case 5:{
7117                int kold = kFI3_show_ref ;
7118 
7119                if( !RWC_do_overfim || RWC_ideal == NULL ){
7120                   XBell(theDisp,100) ; return 0;
7121                }
7122                if( rot_direct == -1 && kFI3_show_ref > 0 ) kFI3_show_ref -- ;
7123                if( rot_direct ==  0 && kFI3_show_ref < 2 ) kFI3_show_ref ++ ;
7124 
7125                if( kold == kFI3_show_ref ){ XBell(theDisp,100) ; return 0; }
7126 
7127                ref_modified = 1 ;   /* force redraw */
7128             }
7129             break ;  /* end of status=5 */
7130 
7131             /*** write current reference to a file ***/
7132 
7133             case 6:{
7134                float val , yscal , yoff ;
7135                float *id ;
7136                int ii , ival ;
7137                FILE * fp ;
7138 
7139                if( !RWC_do_overfim || RWC_ideal == NULL ){
7140                   XBell(theDisp,100) ;
7141                   return 0;
7142                }
7143 
7144                /*** get file name ***/
7145 
7146                txtW_ON = 1;
7147                x       = 50 + GL_DLX;
7148                y       = xtkeys[FIM_first_key].y ;
7149                strp[0] = ASC_NUL ;
7150                take_file_name(theDisp, GWindow , CMap, txtGC, mfinfo, x, y,
7151                               strp, 41, "Filename for Reference Function:", 1 );
7152                txtW_ON = 0 ;
7153                if( strlen(strp) <= 0 ) return 0;
7154 
7155                /*** find scale factor for plot ***/
7156 
7157 	       if( kFI3_refsum_count > 0 ){
7158 		  yscal = 100.0 / kFI3_refsum_count ;
7159 		  yoff  = 0.0 ;
7160                } else {
7161 		  yscal = 1.0 ;
7162 		  yoff  = 0.0 ;
7163                }
7164                id = RWC_ideal->ts ;
7165 
7166 /*** this code is for rescaling the plot to range 0..10000 ***/
7167 #if 0
7168                idmax = -99999.0 ;
7169                idmin =  99999.0 ;
7170 
7171                for( ii=0 ; ii < npoints ; ii++ ){
7172                  val = id[ii] ;
7173                  if( fabs(val) < 33333.0 ){
7174                     idmax = MAX(idmax,val) ;
7175                     idmin = MIN(idmin,val) ;
7176                  }
7177                }
7178                if( idmax >= 33333.0 || idmax <= -33333.0 || idmax <= idmin )
7179                  return 0;
7180 
7181                yscal = 10000.0 / (idmax-idmin) ;
7182                yoff  = idmin ;
7183 #endif
7184                /*** write plot ***/
7185 
7186                fp = fopen( strp , "w" ) ;
7187                if( fp == NULL ){
7188                   fprintf(stderr,"\n*** cannot open file %s\n",strp) ;
7189                   XBell(theDisp,100) ; return 0;
7190                }
7191 
7192                for( ii=0 ; ii < npoints ; ii++ ){
7193                   val  = id[ii] ;
7194                   ival = (fabs(val) < 33333.0) ? (int) (yscal*(val-yoff))
7195                                                : 99999 ;
7196                   fprintf(fp,"%5d\n",ival) ;
7197                }
7198                fclose(fp) ;
7199                fprintf(stderr,"*** wrote plot file %s\n",strp) ;
7200 
7201                return 0;  /* no need to change status, so exit now */
7202             }
7203             break ;  /* end of status=6 */
7204 
7205             /*** increment # of polynomial orts ***/
7206 
7207             case 7:{
7208                int kold = RWC_polort ;
7209 
7210                if( rot_direct == -1 ){
7211                   if( RWC_polort >= 0 ) RWC_polort -- ;
7212                } else if( rot_direct == 0 ){
7213                   if( RWC_polort < MAX_POLORT ) RWC_polort ++ ;
7214                }
7215                if( kold == RWC_polort ){ XBell(theDisp,100) ; return 0; }
7216             }
7217             break ;  /* end of status=7 */
7218 
7219             /*** make current ref file an ort also ***/
7220 
7221             case 8:{
7222 
7223                if( RWC_ideal == NULL || RWC_numort == MAX_NUMORT ){
7224                   XBell(theDisp,100) ; return 0;
7225                }
7226 
7227                RWC_ort[RWC_numort++] = RWC_ideal ;  /* put into ort array */
7228 
7229                /* now, turn fim off, since don't have a ref anymore */
7230 
7231                ref_modified   = 1 ;
7232                RWC_do_overfim = 0 ;
7233                RWC_ideal      = NULL ;
7234                if( RWC_imover != NULL ) {free(RWC_imover); RWC_imover = NULL;}
7235 
7236 	       /* switch to ref=plot status; current status is now useless */
7237 
7238                kFI3_status     = 0 ;
7239                xtkeys[kFI3].st = key_kFI3[kFI3_status] ;
7240                DrawKey(kFI3) ;
7241             }
7242             break ; /* end of status=8 */
7243 
7244             /*** clear all orts ***/
7245 
7246             case 9:{
7247                int ii ;
7248                if( RWC_numort == 0 ){ XBell(theDisp,100) ; return 0; }
7249                for( ii=0 ; ii < RWC_numort ; ii++ ){
7250                   RWC_free_time_series( RWC_ort[ii] ) ;
7251                   RWC_ort[ii] = NULL ;
7252                }
7253                RWC_numort = 0 ;
7254             }
7255             break ; /* end of status=9 */
7256 
7257             /*** modify LSQ_code ***/
7258 
7259             case 10:{
7260                int old_imed = LSQ_imedit[LSQ_code] ;
7261 
7262                if( RWC_ideal == NULL || !RWC_do_overfim || LSQ_fitim == NULL ){
7263                   XBell(theDisp,100) ; return 0;
7264                }
7265 
7266                if( rot_direct   == -1      ) LSQ_code-- ;
7267                if( rot_direct   ==  0      ) LSQ_code++ ;
7268                if( LSQ_code < LSQ_NONE     ) LSQ_code = LSQ_LASTCODE ;
7269                if( LSQ_code > LSQ_LASTCODE ) LSQ_code = LSQ_NONE ;
7270 
7271                DrawTopWindow() ; redraw_graph() ;
7272                old_im = -1 ;
7273                if( old_imed != LSQ_imedit[LSQ_code] && Im_Nr < npoints ) Put_image( Im_Nr ) ;
7274 
7275                return 0;
7276             }
7277             break ;  /* end of status=10 */
7278 
7279          }  /* end of kFI3_status switch */
7280       break ; /* end of ikey=kFI3 */
7281 
7282    }  /* end of ikey switch */
7283 
7284    /*** if we get to here, the user changed something,
7285         so mark the FIM calculations to be redone, and do some graphics ***/
7286 
7287    InvertKey(kFIM) ;  /* flash the FIM key */
7288    DrawTopWindow() ;  /* update the labels */
7289    InvertKey(kFIM) ;
7290 
7291    if( ref_modified ){
7292       redraw_graph() ;
7293       FIM_edit_time_series( RWC_ideal ) ;
7294    }
7295 
7296    FIM_modified = 1 ;
7297    return 0;
7298 }
7299 
7300 /****************************************************************************/
7301 
FIM_edit_time_series(vec)7302 int FIM_edit_time_series( vec )
7303   time_series * vec ;
7304 {
7305    int i , itop ;
7306    if( vec == NULL ) return 0;
7307 
7308    /*** blast out first locations, if requested ***/
7309 
7310    itop = MIN( Im_frst-1 , (vec->len)-1 ) ;
7311    for (i=0; i < itop ; i++) vec->ts[i] = 99999.99 ;
7312 
7313    return 0;
7314 }
7315 
7316 /*--------------------------------------------------------------------------*/
7317 
7318 /*** delete the current image, if possible ***/
7319 
kill_curr_im()7320 int kill_curr_im()
7321 {
7322    int kk ;
7323 
7324    if( Im_Nr < npoints ){ XBell(theDisp,100) ; return 0; }
7325 
7326    mri_free( allim[Im_Nr] ) ;
7327    for( kk=Im_Nr+1 ; kk < N_im ; kk++ ) allim[kk-1] = allim[kk] ;
7328 
7329    N_im-- ;                           /* one less image in the pile */
7330    old_im = -1 ;                      /* mark saved image as invalid */
7331    Im_Nr  = MIN( Im_Nr , N_im-1 ) ;   /* leave Im_Nr same, if possible */
7332 
7333    Put_image(Im_Nr);  /* redisplay */
7334    DrawSubWindow();
7335    DrawTopWindow();
7336    XFlush(theDisp);
7337 
7338    return 0;
7339 }
7340 
7341 /*--------------------------------------------------------------------------*/
7342 
7343 /*** add an extra image onto the end of allim ***/
7344 
add_extra_image(newim)7345 void add_extra_image(newim)
7346      MRI_IMAGE *newim;
7347 {
7348    if( N_im >= dim_allim ){
7349       dim_allim += INC_ALLIM ;
7350       allim      = realloc( allim , sizeof(MRI_IMAGE *) * dim_allim ) ;
7351       if( allim == NULL ){
7352          fprintf(stderr,"\n*** cannot allocate space for new image!\a\n") ;
7353          exit(-1) ;
7354       }
7355    }
7356 
7357    allim[N_im] = mri_to_short( 0.0 , newim ) ;
7358    mri_add_name( newim->name , allim[N_im] ) ;
7359    N_im++ ;
7360 
7361    Im_Nr = N_im - 1 ;
7362 
7363    Put_image(Im_Nr);
7364    DrawSubWindow();
7365    DrawTopWindow();
7366 
7367    return ;
7368 }
7369 
7370 /*----------------------------------------------------------------------*/
read_new_im()7371    int read_new_im()
7372 {
7373    MRI_IMAGE * im ;
7374    int x , y ;
7375 
7376    if ( txtW_ON ) {
7377       XBell(theDisp, 100); return(2);
7378    }
7379    txtW_ON = 1;
7380 
7381    x = 50 + GL_DLX;
7382    y = 50 + GT_DLY;
7383 
7384    strp[0] = ASC_NUL ;
7385    take_file_name(theDisp, GWindow , CMap, txtGC, mfinfo, x, y, strp, 41,
7386                   "Enter input image name:" , 0 );
7387    txtW_ON = 0 ;
7388 
7389    if( strp[0] == '\0' ) return(1) ;
7390 
7391    im = mri_read_nsize( strp ) ;
7392 
7393    /* we have already decided on swapping     27 Aug 2004 [rickr] */
7394 
7395    if ( swap_bytes && im->kind == MRI_short ) {
7396      swap_2(MRI_SHORT_PTR(im), im->nx*im->ny*2);
7397    }
7398    else if ( swap_bytes && im->kind == MRI_float ) {
7399      swap_4(MRI_FLOAT_PTR(im), im->nx*im->ny*4);
7400    }
7401 
7402    if( im == NULL ) return(3) ;
7403 
7404    if( (im->nx != im->ny) ||
7405        ( (im->nx != EPX1) && (im->nx != EPX2) &&
7406          (im->nx != EPX3) && (im->nx != EPX4) && (im->nx != EPX5) ) ){
7407 
7408       fprintf(stderr,"\n*** input file %s has illegal dimensions!\n",strp) ;
7409       mri_free( im ) ;
7410       return(4) ;
7411    }
7412 
7413    add_extra_image( im ) ;
7414    mri_free( im ) ;
7415 
7416    return(0);
7417 }
7418 
7419 /**-------------------------------------------------------------------------**/
7420 
7421 /*** initialize the FIM colors:
7422         from the command line options (in FIM_opt_* variables), OR
7423         from the X11 defaults database (in the fim_* variables), OR
7424         from the default tables (in overfim.h)
7425 ***/
7426 
RWC_init_fim_colors()7427 void RWC_init_fim_colors()
7428 {
7429    char * xdef ;
7430    char stst[32] ;
7431    int ncol = DEFAULT_FIM_COLORS ;  /* defined in overfim.h */
7432    int ii , thr_good ;
7433    XColor test_color ;
7434    float xx ;
7435 
7436    if( FIM_opt_colors > 0 ){
7437       ncol = FIM_opt_colors ;
7438    } else {
7439       xdef = XGetDefault(theDisp,Xdef_Name,"fim_colors") ;
7440       if( xdef != NULL ){
7441          ii = strtol( xdef , NULL , 10 ) ;
7442          if( ii > 0 && ii <= MAX_FIM_COLORS ){
7443             ncol = ii ;
7444          } else {
7445             fprintf(stderr,
7446                     "\n*** illegal fim_colors in X11 database: %s\n",xdef) ;
7447          }
7448       }
7449    }
7450    RWC_fim_colors = ncol ;
7451 
7452    thr_good = 0 ;
7453 
7454    /* read from X defaults or from FIM_opt_* variables */
7455 
7456    for( ii=1 ; ii <= ncol ; ii++ ){
7457 
7458       sprintf( stst , "fim_pos_%d" , ii ) ;
7459       if( FIM_opt_colors > 0 ){
7460          xdef = FIM_opt_pos[ii-1] ;
7461       } else {
7462          xdef = XGetDefault(theDisp,Xdef_Name,stst) ;
7463       }
7464       if( xdef != NULL ){
7465 	 if( check_color(xdef) ) FIM_poscol[ii-1] = xdef ;
7466 	 else
7467             fprintf(stderr,"\n*** illegal FIM color %s replaced by %s\n",
7468                     xdef , FIM_poscol[ii-1] ) ;
7469       }
7470 
7471       sprintf( stst , "fim_neg_%d" , ii ) ;
7472       if( FIM_opt_colors > 0 ){
7473          xdef = FIM_opt_neg[ii-1] ;
7474       } else {
7475          xdef = XGetDefault(theDisp,Xdef_Name,stst) ;
7476       }
7477       if( xdef != NULL ){
7478 	 if( check_color(xdef) ) FIM_negcol[ii-1] = xdef ;
7479 	 else
7480             fprintf(stderr,"\n*** illegal FIM color %s replaced by %s\n",
7481                     xdef , FIM_negcol[ii-1] ) ;
7482       }
7483 
7484       if( FIM_opt_colors > 0 ){
7485          RWC_fim_thresh[ncol-ii] = FIM_opt_thr[ii-1] ;
7486          thr_good ++ ;
7487       } else {
7488          sprintf( stst , "fim_thr_%d" , ii ) ;
7489          xdef = XGetDefault(theDisp,Xdef_Name,stst) ;
7490          if( xdef != NULL ){
7491             xx = strtod( xdef , NULL ) ;
7492             if( xx > 0.0 && xx < 1.0 ){
7493                RWC_fim_thresh[ncol-ii] = xx ;
7494                thr_good ++ ;
7495             } else {
7496                fprintf(stderr,"\n*** illegal FIM threshold %s being replaced\n",
7497                        xdef ) ;
7498             }
7499          }
7500       }  /* end if FIM_opt_colors */
7501 
7502    }  /* end for ii */
7503 
7504    /*** check if thresholds are all good ***/
7505 
7506    if( thr_good > 0 && thr_good < ncol ){
7507       fprintf(stderr,"\n*** input thresholds being replaced!\n") ;
7508    }
7509 
7510    if( thr_good < ncol ){
7511       float dth = 0.95 / ncol ;
7512       for( ii=0 ; ii < ncol ; ii++ ) RWC_fim_thresh[ii] = 0.05 + ii*dth ;
7513    }
7514 
7515    if( thr_good > 0 && thr_good < ncol ){
7516       for( ii=0 ; ii < ncol ; ii++ )
7517          fprintf(stderr,"%5.2f ",RWC_fim_thresh[ii]);
7518    }
7519 
7520    /*** now, actually put color indices into place ***/
7521 
7522    for( ii=0 ; ii < ncol ; ii++ ){
7523       int rr,gg,bb ;
7524 
7525       XParseColor(theDisp,CMap,FIM_poscol[ncol-ii-1],&test_color) ;
7526       rr = test_color.red ;
7527       gg = test_color.green ;
7528       bb = test_color.blue ;
7529 
7530       add_extra_color( rr,gg,bb , NUM_STD_COLORS + ii + 1) ;
7531       RWC_fim_colors_pos[ii] =  -(NUM_STD_COLORS + ii + 1) ;
7532 
7533       XParseColor(theDisp,CMap,FIM_negcol[ncol-ii-1],&test_color) ;
7534       rr = test_color.red ;
7535       gg = test_color.green ;
7536       bb = test_color.blue ;
7537 
7538       add_extra_color( rr,gg,bb , NUM_STD_COLORS + ncol + ii + 1) ;
7539       RWC_fim_colors_neg[ii] =  -(NUM_STD_COLORS + ncol + ii + 1) ;
7540    }
7541    return ;
7542 }
7543 
7544 /*-------------------------------------------------------------------------*/
7545 
7546 /*** add a color with the given r,g,b values to the extra_colors table
7547      (see routine STD_colors)
7548 ***/
7549 
add_extra_color(r,g,b,ind)7550 void add_extra_color(r, g, b, ind)
7551      int r;
7552      int g;
7553      int b;
7554      int ind;
7555 {
7556    XColor any_col;
7557    int    ic ;
7558    char *cH;
7559    char  *a8;
7560    short *a16;
7561 
7562    ic = ind - NUM_STD_COLORS ;
7563    if( ic < 1 || ic > MAX_EXTRA_COLORS ){
7564       fprintf(stderr,"\n*** illegal call to add_extra_color()!\a\n");
7565       exit(-1) ;
7566    }
7567 
7568    any_col.red   = r ; any_col.green = g ; any_col.blue = b ;
7569    any_col.flags = DoRed | DoGreen | DoBlue;
7570 
7571    if ( AJ_PseudoColor ) {
7572       if( !XAllocColor(theDisp, CMap, &any_col) )
7573          FatalError ("XAllocColor problem in add_extra_color(). RWC");
7574       extra_color_x11[ic-1] = any_col.pixel ;
7575    }
7576    else {
7577       switch( bperpix ) {
7578          case 32:
7579          default:
7580             cH = (char *) &AJ_RGB[ind + NCOLORS - 1];
7581          break;
7582          case 24:
7583             a8 = (char *) AJ_RGB;
7584             cH = a8 + (ind + NCOLORS - 1) * 3;
7585          break;
7586          case 16:
7587             a16 = (short *) AJ_RGB;
7588             cH = (char *) &a16[ind + NCOLORS - 1];
7589          break;
7590          case 8:
7591             a8 = (char *) AJ_RGB;
7592             cH = (char *) &a8[ind + NCOLORS - 1];
7593          break;
7594       }
7595 
7596       AJ_rgb[0].r = (r >> 8) & 0xff;
7597       AJ_rgb[0].g = (g >> 8) & 0xff;
7598       AJ_rgb[0].b = (b >> 8) & 0xff;
7599       Make_RGB_lookup(AJ_rgb, cH, 1);
7600    }
7601 }
7602 
7603 /* ----------------------------------------------------------------------- */
7604 
7605 /*** check that a character string is a valid color name ***/
7606 
check_color(cname)7607 int check_color( cname )
7608   char * cname ;
7609 {
7610    XColor test_color ;
7611 
7612    return XParseColor(theDisp,CMap,cname,&test_color) ;
7613 }
7614 
7615 /* --------------- */
dec_indx(n)7616    int dec_indx(n)
7617    int n;
7618 /* --------------- */
7619 {
7620    int m;
7621 
7622    m = 0;
7623    while (n) {
7624       n /= 10;
7625       m++;
7626    }
7627    return (m);
7628 }
7629 
7630 /* -------------------- */
Get_X_Y(mx,my)7631    int Get_X_Y(mx, my)
7632    int *mx, *my;
7633 /* -------------------- */
7634 {
7635    Window       rW, cW;
7636    u_int        key;
7637    int          x, y, rx, ry;
7638 
7639    if ( XQueryPointer(theDisp, theWindow, &rW, &cW,
7640                                 &rx, &ry, &x, &y, &key) ) {
7641       if ( (x < eWIDE) && (y < eHIGH) ) {
7642          *mx = Mltx[x]/x_mag;
7643          *my = Mlty[y]/x_mag;
7644          return(1);
7645       }
7646       else
7647          return(0);
7648    }
7649    else
7650       return(0);
7651 }
7652 
7653 /* ----------------------- */
7654    void
swap_2(arR,nr)7655    swap_2(arR, nr)
7656    char *arR;
7657    int nr;
7658 /* ----------------------- */
7659 {
7660    int i;
7661    char ctmp;
7662 
7663    for (i=0; i < nr; i+=2){
7664      ctmp     = arR[i+1];
7665      arR[i+1] = arR[i];
7666      arR[i]   = ctmp;
7667    }
7668 }
7669 
7670 /* ----------------------- */
7671    void
swap_4(arR,nr)7672    swap_4(arR, nr)
7673    char *arR;
7674    int nr;
7675 /* ----------------------- */
7676 {
7677    int i;
7678    char ctmp2, ctmp3;
7679 
7680    for (i=0; i < nr; i+=4){
7681      ctmp3    = arR[i+3];
7682      ctmp2    = arR[i+2];
7683      arR[i+2] = arR[i+1];
7684      arR[i+3] = arR[i];
7685      arR[i]   = ctmp3;
7686      arR[i+1] = ctmp2;
7687    }
7688 }
7689 
7690 /* ----------------------------------------- */
7691    void
AJ_StoreColors(Disp,cmap,mc,nc,color)7692    AJ_StoreColors(Disp, cmap, mc, nc, color)
7693    Display   *Disp;
7694    Colormap  cmap;
7695    XColor    *mc;
7696    int       nc, color;
7697 /* ----------------------------------------- */
7698 {
7699    int i;
7700    if ( color ) {                    /* correction for inverse order AAJ */
7701       for (i=0; i < nc; i++) {
7702          AJ_rgb[nc-i-1].r = mc[i].red >> 8;
7703          AJ_rgb[nc-i-1].g = mc[i].green >> 8;
7704          AJ_rgb[nc-i-1].b = mc[i].blue >> 8;
7705       }
7706    }
7707    else {
7708       for (i=0; i < nc; i++) {
7709          AJ_rgb[i].r = mc[i].red >> 8;
7710          AJ_rgb[i].g = mc[i].green >> 8;
7711          AJ_rgb[i].b = mc[i].blue >> 8;
7712       }
7713    }
7714    Make_RGB_lookup(AJ_rgb, AJ_RGB, nc);
7715    if ( expImage != NULL )  Put_image(Im_Nr);
7716 }
7717 
7718 /* --------------------------------- create machine packed RGB values */
7719    void
Make_RGB_lookup(in,out,nc)7720    Make_RGB_lookup(in, out, nc)
7721    AJ_rgb_str *in;
7722    char *out;
7723    int nc;
7724 /* --------------------------------- */
7725 {
7726    unsigned int  r, g, b, rmask, gmask, bmask;
7727    int           rshift, gshift, bshift, i, *xcol;
7728    byte          *ip;
7729 
7730    rmask = theVisual->red_mask;   rshift = 7 - highbit(rmask);
7731    gmask = theVisual->green_mask; gshift = 7 - highbit(gmask);
7732    bmask = theVisual->blue_mask;  bshift = 7 - highbit(bmask);
7733 
7734    xcol = (int *) malloc(sizeof(int) * nc);
7735    for (i=0; i < nc; i++) {
7736       r = in[i].r;
7737       g = in[i].g;
7738       b = in[i].b;
7739       r = (rshift<0) ? (r<<(-rshift)) : (r>>rshift); r = r & rmask;
7740       g = (gshift<0) ? (g<<(-gshift)) : (g>>gshift); g = g & gmask;
7741       b = (bshift<0) ? (b<<(-bshift)) : (b>>bshift); b = b & bmask;
7742       xcol[i] = r | g | b;
7743    }
7744 
7745    ip = (byte *) out;
7746    switch( bperpix ) {
7747       case 32:
7748         if (border == MSBFirst)
7749            for( i=0 ; i < nc ; i++ ){
7750               *ip++ = (xcol[i]>>24) & 0xff ;
7751               *ip++ = (xcol[i]>>16) & 0xff ;
7752               *ip++ = (xcol[i]>>8)  & 0xff ;
7753               *ip++ =  xcol[i]      & 0xff ;
7754             }
7755         else
7756            for( i=0 ; i < nc ; i++ ){
7757               *ip++ =  xcol[i]      & 0xff ;
7758               *ip++ = (xcol[i]>>8)  & 0xff ;
7759               *ip++ = (xcol[i]>>16) & 0xff ;
7760               *ip++ = (xcol[i]>>24) & 0xff ;
7761             }
7762       break ;
7763 
7764       case 24:
7765         if (border == MSBFirst)
7766            for( i=0 ; i < nc ; i++ ){
7767              *ip++ = (xcol[i]>>16) & 0xff ;
7768              *ip++ = (xcol[i]>>8)  & 0xff ;
7769              *ip++ =  xcol[i]      & 0xff ;
7770            }
7771         else
7772            for( i=0 ; i < nc ; i++ ){
7773              *ip++ =  xcol[i]      & 0xff ;
7774              *ip++ = (xcol[i]>>8)  & 0xff ;
7775              *ip++ = (xcol[i]>>16) & 0xff ;
7776            }
7777       break ;
7778 
7779       case 16:
7780         if (border == MSBFirst)
7781            for( i=0 ; i < nc ; i++ ){
7782              *ip++ = (xcol[i]>>8)  & 0xff ;
7783              *ip++ =  xcol[i]      & 0xff ;
7784            }
7785         else
7786            for( i=0 ; i < nc ; i++ ){
7787              *ip++ =  xcol[i]      & 0xff ;
7788              *ip++ = (xcol[i]>>8)  & 0xff ;
7789            }
7790       break ;
7791 
7792       case 8:
7793            for( i=0 ; i < nc ; i++ )
7794               *ip++ = xcol[i] & 0xff ;
7795       break ;
7796    }
7797 }
7798 
7799 /* ---------------------------------- */
7800    void
AJ_make_STDcol(mc,nc)7801    AJ_make_STDcol(mc, nc)
7802    struct S_16_c  *mc;
7803    int    nc;
7804 /* ---------------------------------- */
7805 {
7806    int i;
7807    char *cH;
7808    unsigned char *a8;
7809    short *a16;
7810 
7811    switch( bperpix ) {
7812       case 32:
7813       default:
7814          cH = (char *) &AJ_RGB[NCOLORS];
7815       break;
7816       case 24:
7817          a8 = (unsigned char *) AJ_RGB;
7818          cH = (char *) a8 + NCOLORS * 3;
7819       break;
7820       case 16:
7821          a16 = (short *) AJ_RGB;
7822          cH = (char *) &a16[NCOLORS];
7823       break;
7824       case 8:
7825          a8 = (unsigned char *) AJ_RGB;
7826          cH = (char *) &a8[NCOLORS];
7827       break;
7828    }
7829 
7830    for (i=0; i < nc; i++) {
7831       AJ_rgb[i].r = mc[i].red >> 8;
7832       AJ_rgb[i].g = mc[i].green >> 8;
7833       AJ_rgb[i].b = mc[i].blue >> 8;
7834    }
7835    Make_RGB_lookup(AJ_rgb, cH, nc);
7836 }
7837 
7838 /* ------------- */
7839    int
AJ_init_RGB()7840    AJ_init_RGB()
7841 /* ------------- */
7842 {
7843    int i;
7844    XImage *tstImage;
7845    tstImage = XCreateImage(theDisp, theVisual, Planes, ZPixmap,
7846                            0, NULL, 16, 16, 32, 0);
7847    if ( tstImage == NULL ) return 1;
7848    bperpix = tstImage->bits_per_pixel;
7849    border  = tstImage->byte_order;
7850    XDestroyImage(tstImage);
7851   /* AJ our order for RGB */
7852    for (i=0; i < (NCOLORS); i++) pixels[i] = i;
7853    for (i=0; i < (NUM_STD_COLORS + MAX_EXTRA_COLORS); i++)
7854       STD_indx[i] = NCOLORS + i;
7855 
7856    return 0;
7857 }
7858 
7859 /*------------------------------------------------------------------------
7860   Returns position of highest set bit in 'ul' as an integer (0-31),
7861   or returns -1 if no bit is set.
7862 --------------------------------------------------------------------------*/
7863 /* ------------------------- */
7864    static int
highbit(unsigned int ul)7865    highbit(unsigned int ul)
7866 /* ------------------------- */
7867 {
7868   int i;  unsigned int hb;
7869 
7870   hb = 0x80;  hb = hb << 24;   /* hb = 0x80000000UL */
7871   for (i=31; ((ul & hb) == 0) && i>=0;  i--, ul<<=1);
7872   return i;
7873 }
7874