00001 
00002 
00003 
00004 
00005 
00006 
00007 #include <stdio.h>
00008 #include <string.h>
00009 #include <errno.h>       
00010 #include <X11/keysym.h>  
00011 
00012 #undef IMSEQ_DEBUG
00013 
00014 #include "mrilib.h"
00015 #include "imseq.h"
00016 #include "xutil.h"
00017 #include "xim.h"
00018 
00019 #if 0                   
00020 # undef  DBG_trace
00021 # define DBG_trace 2
00022 #endif
00023 
00024 #define DPR(st) STATUS(st)
00025 #define DPRI(st,ijk) \
00026   if(PRINT_TRACING){ char str[256]; sprintf(str,"%s %d",st,ijk); STATUS(str); }
00027 
00028 #define COLSIZE AV_colsize()  
00029 
00030 #define DONT_ONOFF_ONE        
00031 
00032 #define SEND(sq,cb)                                     \
00033   AFNI_CALL_VOID_3ARG( (sq)->status->send_CB ,          \
00034                        MCW_imseq * , sq ,               \
00035                        XtPointer   , (sq)->getaux ,     \
00036                        ISQ_cbs *   , &(cb)          )
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 #define NACT_DISP 2  
00045 #define DISP_OK   1  
00046 #define DISP_UNDO 0
00047 
00048 static MCW_action_item ISQ_disp_act[NACT_DISP] = {
00049  {"Reset",ISQ_disp_act_CB,NULL,"Sets all options back\nto earlier values","Undo changes", 0 },
00050  {"Done" ,ISQ_disp_act_CB,NULL,"Closes this window"                      ,"Close window", 1 }
00051 } ;
00052 
00053 
00054 
00055                        
00056 #define NBUT_DISP1  4  
00057 #define NBUT_DISP2  1  
00058 #define NBUT_DISP3  1  
00059 #define NBUT_DISP4  2  
00060 #define NBUT_DISP5  2  
00061 #define NBUT_DISP6  1  
00062 #define NBUT_DISP7  2                
00063 #define NBUT_DISP8  3  
00064 #define NBUT_DISP9  4  
00065 
00066 #define NTOG_ROT  0  
00067 #define NTOG_MIR  1
00068 #define NTOG_COL  2
00069 #define NTOG_RNG  3
00070 #define NTOG_SCL  4
00071 #define NTOG_ASP  5
00072 #define NTOG_SAV  6
00073 #define NTOG_IMP  7
00074 #define NTOG_CX   8
00075 
00076 static char * ISQ_dl1[NBUT_DISP1] = {
00077    "No Rotation" , "CCW 90" , "Rot 180" , "CW 90" } ;
00078 static char * ISQ_dl2[NBUT_DISP2] = { "+ LR Mirror" } ;
00079 static char * ISQ_dl3[NBUT_DISP3] = { "No Overlay" } ;
00080 static char * ISQ_dl4[NBUT_DISP4] = { "Min-to-Max" , "2%-to-98%" } ;
00081 static char * ISQ_dl5[NBUT_DISP5] = { "Autoscale" , "Groupscale" } ;
00082 static char * ISQ_dl6[NBUT_DISP6] = { "Free Aspect" } ;
00083 static char * ISQ_dl7[NBUT_DISP7] = { "Nsize Save" , "PNM Save" } ;
00084 static char * ISQ_dl8[NBUT_DISP8] = { "Flatten" , "Sharpen" , "Edge Detect" } ;
00085 static char * ISQ_dl9[NBUT_DISP9] = {
00086    "Complex->Mag" , "Complex->Arg" , "Complex->Real" , "Complex->Imag" } ;
00087 
00088 static ISQ_boxdef ISQ_dispbb[] = {
00089    { NBUT_DISP1 , ISQ_dl1 , MCW_BB_radio_one  , MCW_BB_frame } ,
00090    { NBUT_DISP2 , ISQ_dl2 , MCW_BB_check      , MCW_BB_frame } ,
00091    { NBUT_DISP3 , ISQ_dl3 , MCW_BB_check      , MCW_BB_frame } ,
00092    { NBUT_DISP4 , ISQ_dl4 , MCW_BB_radio_one  , MCW_BB_frame } ,
00093    { NBUT_DISP5 , ISQ_dl5 , MCW_BB_radio_one  , MCW_BB_frame } ,
00094    { NBUT_DISP6 , ISQ_dl6 , MCW_BB_check      , MCW_BB_frame } ,
00095    { NBUT_DISP7 , ISQ_dl7 , MCW_BB_radio_zero , MCW_BB_frame } ,
00096    { NBUT_DISP8 , ISQ_dl8 , MCW_BB_check      , MCW_BB_frame } ,
00097    { NBUT_DISP9 , ISQ_dl9 , MCW_BB_radio_one  , MCW_BB_frame } ,
00098 } ;
00099 
00100 static char * ISQ_bb1_help[NBUT_DISP1] = {
00101    "Sets orientation to the\noriginal in the data set" ,
00102    "Rotate 90 degrees\ncounterclockwise\nfrom original" ,
00103    "Rotate 180 degrees\nfrom original" ,
00104    "Rotate 90 degrees\nclockwise\nfrom original"
00105 } ;
00106 
00107 static char * ISQ_bb1_hint[NBUT_DISP1] = {
00108    "No extra rotation of image" ,
00109    "90 degrees counterclockwise" ,
00110    "Rotate 180 degrees" ,
00111    "90 degrees clockwise"
00112 } ;
00113 
00114 static char * ISQ_bb2_help[NBUT_DISP2] = {
00115    "pressed IN means\nleft-right mirror AFTER rotation"
00116 } ;
00117 
00118 static char * ISQ_bb2_hint[NBUT_DISP2] = {
00119    "IN: mirror image AFTER rotation"
00120 } ;
00121 
00122 static char * ISQ_bb3_help[NBUT_DISP3] = {
00123    "pressed IN means\nturn color overlays off"
00124 } ;
00125 
00126 static char * ISQ_bb3_hint[NBUT_DISP3] = {
00127    "IN: turn color overlays off"
00128 } ;
00129 
00130 static char * ISQ_bb4_help[NBUT_DISP4] = {
00131  "Intensities mapped\nover full range of data\n(min->lowest,max->highest)" ,
00132  "Intensities mapped\nover partial range of data\n(%ages in data histogram)"
00133 } ;
00134 
00135 static char * ISQ_bb4_hint[NBUT_DISP4] = {
00136  "Background intensity = min to max pixel values" ,
00137  "Background intensity = 2% to 98% pixel values"
00138 } ;
00139 
00140 static char * ISQ_bb5_help[NBUT_DISP5] = {
00141    "Intensities mapped\nfor each image separately" ,
00142    "Intensities mapped\nfor all images in common"
00143 } ;
00144 
00145 static char * ISQ_bb5_hint[NBUT_DISP5] = {
00146    "Intensities computed for each slice" ,
00147    "Intensities computed for all slices at once"
00148 } ;
00149 
00150 static char * ISQ_bb6_help[NBUT_DISP6] = {
00151  "pressed IN means allow arbitrary resizing of window\n"
00152  "pressed OUT means restrict window aspect ratio"
00153 } ;
00154 
00155 static char * ISQ_bb6_hint[NBUT_DISP6] = {
00156  "IN: Allow arbitrary resizing of window"
00157 } ;
00158 
00159 static char * ISQ_bb7_help[NBUT_DISP7] = {
00160  "Nsize: IN = 'normal' (power of 2)  saved images sizes\n"
00161  "       OUT= 'natural' (data given) saved images sizes"   ,
00162 
00163  "PNM:   IN = saved images are color (PNM format)\n"
00164  "       OUT= saved images are background data only\n"
00165 } ;
00166 
00167 static char * ISQ_bb7_hint[NBUT_DISP7] = {
00168  "IN: Save background images in power-of-2 sizes" ,
00169  "IN: Save background images in PNM format"
00170 } ;
00171 
00172 static char * ISQ_bb8_help[NBUT_DISP8] = {
00173  "Flatten: IN = Flatten histogram of background\n"
00174  "         OUT= Don't flatten histogram\n"                      ,
00175 
00176  "Sharpen: IN = Apply sharpening filter to background\n"
00177  "         OUT= Don't apply sharpening filter"                  ,
00178 
00179  "Edge: IN = Use Sobel edge detection filter on background\n"
00180  "      OUT= Don't use Sobel edge detector"
00181 } ;
00182 
00183 static char * ISQ_bb8_hint[NBUT_DISP8] = {
00184  "Flatten histogram of background" ,
00185  "Apply sharpening filter to background" ,
00186  "Apply Sobel edge detector to background"
00187 } ;
00188 
00189 #define ISQ_CX_HELP                            \
00190   "Complex-> options control how complex-\n"   \
00191   "valued images are displayed:\n"             \
00192   "  ->Mag  == Display magnitude\n"            \
00193   "  ->Arg  == Display argument (phase)\n"     \
00194   "  ->Real == Display real part\n"            \
00195   "  ->Imag == Display imaginary part"
00196 
00197 static char * ISQ_bb9_help[NBUT_DISP9] = {
00198   ISQ_CX_HELP , ISQ_CX_HELP , ISQ_CX_HELP , ISQ_CX_HELP
00199 } ;
00200 
00201 static char * ISQ_bb9_hint[NBUT_DISP9] = {
00202   "Display magnitude" ,
00203   "Display argument (phase)"
00204   "Display real part" ,
00205   "Display imaginary part"
00206 } ;
00207 
00208 static char ** ISQ_bb_allhelp[] = {
00209   ISQ_bb1_help , ISQ_bb2_help , ISQ_bb3_help ,
00210   ISQ_bb4_help , ISQ_bb5_help , ISQ_bb6_help ,
00211   ISQ_bb7_help , ISQ_bb8_help , ISQ_bb9_help
00212 } ;
00213 
00214 static char ** ISQ_bb_allhint[] = {
00215   ISQ_bb1_hint , ISQ_bb2_hint , ISQ_bb3_hint ,
00216   ISQ_bb4_hint , ISQ_bb5_hint , ISQ_bb6_hint ,
00217   ISQ_bb7_hint , ISQ_bb8_hint , ISQ_bb9_hint
00218 } ;
00219 
00220 
00221 
00222 
00223 static char ** ppmto_filter  = NULL ;
00224 static char ** ppmto_suffix  = NULL ;
00225 static int   * ppmto_bval    = NULL ;
00226 static int     ppmto_num     = -1 ;
00227 
00228 static char *  ppmto_gif_filter  = NULL ;   
00229 static char *  ppmto_agif_filter = NULL ;
00230 
00231 #define USE_GIFF  
00232 #ifdef  USE_GIFF
00233 static char *  ppmto_giff_filter = NULL ;   
00234 #define GIFF_MAPFILE "Qwerty53211.ppm"
00235 #endif
00236 
00237 static char *  ppmto_mpeg_filter = NULL ;   
00238 static char *  ppmto_ppm_filter  = NULL ;
00239 
00240 static char *  ppmto_jpg75_filter = NULL ;  
00241 static char *  ppmto_jpg95_filter = NULL ;  
00242 
00243  
00244  
00245 
00246 #define GIFSICLE_SUFFIX    "-O2 -d %d -k 127 -l %%s > %%s"
00247 #define WHIRLGIF_SUFFIX    "-time %d -loop %%s > %%s"
00248 #define MPEG_ENCODE_SUFFIX "-realquiet %s"
00249 
00250 #define DO_AGIF(sq) ((sq)->opt.save_agif)
00251 #define DO_MPEG(sq) ((sq)->opt.save_mpeg)
00252 #define DO_ANIM(sq) (DO_AGIF(sq) || DO_MPEG(sq))
00253 
00254 #define ADDTO_PPMTO(pnam,suff,bbb)                                       \
00255   do{ ppmto_filter = (char **) realloc( ppmto_filter ,                   \
00256                                         sizeof(char *)*(ppmto_num+1) ) ; \
00257       ppmto_suffix = (char **) realloc( ppmto_suffix  ,                  \
00258                                         sizeof(char *)*(ppmto_num+1) ) ; \
00259       ppmto_bval   = (int *)   realloc( ppmto_bval    ,                  \
00260                                         sizeof(int)   *(ppmto_num+1) ) ; \
00261       ppmto_filter[ppmto_num] = (pnam) ;                                 \
00262       ppmto_suffix[ppmto_num] = (suff) ;                                 \
00263       ppmto_bval  [ppmto_num] = (bbb)  ; ppmto_num++ ;                   \
00264       if( dbg ) fprintf(stderr,"IMSAVE: filter '%s' for suffix '%s'\n",  \
00265                         (pnam) , (suff) ) ;                              \
00266   } while(0)
00267 
00268 
00269 
00270 #define CANT_FIND(nm,fm)                                                 \
00271  do{ if( !AFNI_noenv("AFNI_IMSAVE_WARNINGS") ){                          \
00272       if( ncant == 0 )                                                   \
00273        fprintf(stderr,"\n++++++++ IMAGE SAVE SETUP WARNINGS ++++++++\n");\
00274       fprintf(stderr,                                                    \
00275               "++ Can't find program %s for Save to %s\n",(nm),(fm)) ;   \
00276      } ncant++ ;                                                         \
00277  } while(0)
00278 
00279 
00280 
00281 static void ISQ_setup_ppmto_filters(void)
00282 {
00283    char *pg , *pg2 , *str , *eee ;
00284    int bv ;
00285    int dbg ;
00286    int ncant=0 , need_netpbm=0 ;  
00287 
00288    ppmto_num = 0 ; bv = ISQ_SAV_PNM ;
00289 
00290    dbg = AFNI_yesenv("AFNI_IMSAVE_DEBUG") ;  
00291 
00292    
00293    
00294 
00295    pg = THD_find_executable( "cat" ) ;   
00296    if( pg != NULL ){
00297       str = AFMALL( char, strlen(pg)+32) ;
00298       sprintf(str,"%s > %%s",pg) ;
00299       bv <<= 1 ; ADDTO_PPMTO(str,"ppm",bv) ;
00300 
00301       
00302 
00303       ppmto_ppm_filter = str ;  
00304 
00305       pg = THD_find_executable( "mpeg_encode" ) ;
00306       if( pg != NULL ){
00307          str = AFMALL( char, strlen(pg)+64) ;
00308          sprintf(str,"%s %s",pg,MPEG_ENCODE_SUFFIX) ;
00309          ppmto_mpeg_filter = str ;
00310          if( dbg ) fprintf(stderr,"IMSAVE: animation filter '%s' for suffix '%s'\n",
00311                            str , "mpg" ) ;
00312       }
00313       else CANT_FIND("mpeg_encode","MPEG-1") ;
00314    }
00315    else CANT_FIND("cat","PPM") ;  
00316 
00317    
00318 
00319    pg = THD_find_executable( "cjpeg" ) ;
00320    if( pg != NULL ){
00321       str = AFMALL( char, strlen(pg)+32) ;
00322       sprintf(str,"%s -quality 95 > %%s",pg) ;
00323       bv <<= 1 ; ADDTO_PPMTO(str,"jpg",bv) ;
00324       ppmto_jpg95_filter = strdup(str) ;  
00325 
00326       
00327 
00328       ppmto_jpg75_filter = AFMALL( char, strlen(pg)+32);
00329       sprintf(ppmto_jpg75_filter,"%s -quality 80 > %%s",pg) ;
00330    }
00331    else CANT_FIND("cjpeg","JPEG") ;
00332 
00333    
00334 
00335    pg  = THD_find_executable( "ppmtogif" ) ;
00336    pg2 = THD_find_executable( "ppmquant" ) ;
00337    if( pg != NULL && pg2 != NULL ){
00338       int adel=20 ; char asuff[64] ;               
00339 
00340       str = AFMALL( char, strlen(pg)+strlen(pg2)+32) ;
00341       sprintf(str,"%s 255 | %s > %%s",pg2,pg) ;
00342       bv <<= 1 ; ADDTO_PPMTO(str,"gif",bv) ;
00343 
00344       
00345 
00346       ppmto_gif_filter = str ;  
00347 
00348 #ifdef USE_GIFF                       
00349       str = AFMALL( char , strlen(pg)+128 ) ;           
00350       sprintf(str,"%s -map %s > %%s",pg,GIFF_MAPFILE) ;
00351       ppmto_giff_filter = str ;
00352 #endif
00353 
00354       
00355 
00356       eee = getenv( "AFNI_AGIF_DELAY" ) ;
00357       if( eee != NULL ){ adel=(int)strtod(eee,NULL); if(adel < 2)adel=20; }
00358 
00359       pg = THD_find_executable( "gifsicle" ) ;    
00360       if( pg != NULL ){
00361          sprintf(asuff,GIFSICLE_SUFFIX,adel) ;    
00362          str = AFMALL( char, strlen(pg)+64) ;
00363          sprintf(str,"%s %s",pg,asuff) ;
00364          ppmto_agif_filter = str ;
00365          if( dbg ) fprintf(stderr,"IMSAVE: animation filter '%s' for suffix '%s'\n",
00366                            str , "gif" ) ;
00367       } else {
00368          pg = THD_find_executable( "whirlgif" ) ; 
00369          if( pg != NULL ){
00370             sprintf(asuff,WHIRLGIF_SUFFIX,adel) ; 
00371             str = AFMALL( char, strlen(pg)+64) ;
00372             sprintf(str,"%s %s",pg,asuff) ;
00373             ppmto_agif_filter = str ;
00374             if( dbg ) fprintf(stderr,"IMSAVE: animation filter '%s' for suffix '%s'\n",
00375                               str , "gif" ) ;
00376          }
00377       }
00378       if( ppmto_agif_filter == NULL )
00379         CANT_FIND("gifsicle OR whirlgif","Animated GIF") ;
00380    }
00381    else { CANT_FIND("ppmtogif AND/OR ppmquant","GIF"); need_netpbm++; }
00382 
00383    
00384 
00385    pg = THD_find_executable( "ppm2tiff" ) ;
00386    if( pg != NULL ){
00387       str = AFMALL( char, strlen(pg)+32) ;
00388       sprintf(str,"%s -c none %%s",pg) ;
00389       bv <<= 1 ; ADDTO_PPMTO(str,"tif",bv) ;
00390    } else {                                     
00391       pg = THD_find_executable( "pnmtotiff" ) ; 
00392       if( pg != NULL ){                         
00393          str = AFMALL( char, strlen(pg)+32) ;   
00394          sprintf(str,"%s > %%s",pg) ;
00395          bv <<= 1 ; ADDTO_PPMTO(str,"tif",bv) ;
00396       }
00397       else { CANT_FIND("ppm2tiff OR pnmtotiff","TIFF"); need_netpbm++; }
00398    }
00399 
00400    
00401 
00402    pg  = THD_find_executable( "ppmtobmp" ) ;
00403 
00404    if( AFNI_yesenv("AFNI_OLD_PPMTOBMP") ){    
00405      pg2 = THD_find_executable( "ppmquant" ) ;
00406      if( pg != NULL && pg2 != NULL ){
00407         str = AFMALL( char, strlen(pg)+strlen(pg2)+32) ;
00408         sprintf(str,"%s 255 | %s -windows > %%s",pg2,pg) ;
00409         bv <<= 1 ; ADDTO_PPMTO(str,"bmp",bv) ;
00410      }
00411      else { CANT_FIND("ppmtobmp AND/OR ppmquant","BMP"); need_netpbm++; }
00412    } else if( pg != NULL ){                   
00413       str = AFMALL( char, strlen(pg)+32) ;
00414       sprintf(str,"%s -bpp 24 -windows > %%s",pg) ;
00415       bv <<= 1 ; ADDTO_PPMTO(str,"bmp",bv) ;
00416    }
00417    else { CANT_FIND("ppmtobmp","BMP"); need_netpbm++; }
00418 
00419    
00420 
00421    pg = THD_find_executable( "pnmtops" ) ;
00422    if( pg != NULL ){
00423       str = AFMALL( char, strlen(pg)+32) ;
00424       sprintf(str,"%s -noturn > %%s",pg) ;
00425       bv <<= 1 ; ADDTO_PPMTO(str,"eps",bv) ;
00426    }
00427    else { CANT_FIND("pnmtops","EPS"); need_netpbm++; }
00428 
00429    
00430 
00431    pg2 = THD_find_executable( "epstopdf" ) ;   
00432    if( pg != NULL && pg2 != NULL ){            
00433       str = AFMALL( char, strlen(pg)+strlen(pg2)+32) ;
00434       sprintf(str,"%s -noturn | %s --filter > %%s",pg,pg2) ;
00435       bv <<= 1 ; ADDTO_PPMTO(str,"pdf",bv) ;
00436    }
00437    else CANT_FIND("pnmtops AND/OR epstopdf","PDF") ;
00438 
00439    
00440 
00441    pg = THD_find_executable( "pnmtopng" ) ;
00442    if( pg != NULL ){
00443       str = AFMALL( char, strlen(pg)+32) ;
00444       sprintf(str,"%s -compression 9 > %%s",pg) ;
00445       bv <<= 1 ; ADDTO_PPMTO(str,"png",bv) ;
00446    }
00447    else { CANT_FIND("pnmtopng","PNG"); need_netpbm; }
00448 
00449    
00450 
00451    if( !AFNI_noenv("AFNI_IMSAVE_WARNINGS") && ncant > 0 ){
00452      if( need_netpbm > 0 )
00453        fprintf(stderr,
00454                "++ Some of the missing image Save programs are in\n"
00455                "    the netpbm software package, which is freeware.\n" ) ;
00456 
00457      fprintf(stderr,
00458                "++ To disable these warnings, set environment\n"
00459                "    variable AFNI_IMSAVE_WARNINGS to 'NO'.\n"
00460                "+++++++++++++++++++++++++++++++++++++++++++\n" ) ;
00461    }
00462 
00463    return ;
00464 }
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 static const ISQ_bdef ISQ_but_bot_def[NBUTTON_BOT] = {  
00505      { "Disp"     , ISQ_but_disp_CB } ,
00506      { "Save:bkg" , ISQ_but_save_CB } ,
00507      { "Mont"     , ISQ_montage_CB  } ,
00508      { "Done"     , ISQ_but_done_CB }
00509 } ;
00510 
00511 static const Boolean ISQ_but_bot_dial[NBUTTON_BOT] = {  
00512    True , False , True , False
00513 } ;
00514 
00515 static char * ISQ_but_done_label1 = "Done" ;
00516 static char * ISQ_but_done_label2 = "DONE" ;
00517 #define NBUT_DONE (NBUTTON_BOT-1)
00518 #define NBUT_SAVE 1
00519 #define NBUT_DISP 0
00520 #define NBUT_MONT 2
00521 
00522 static char * ISQ_save_label_bg  = "Save:bkg" ;
00523 static char * ISQ_save_label_all = "Save:pnm" ;
00524 
00525 #define SET_SAVE_LABEL(seq)                                               \
00526   do{ char sl[16] ;                                                       \
00527       if( (seq)->opt.save_filter < 0 ){                                   \
00528          strcpy(sl, (seq)->opt.save_pnm ? ISQ_save_label_all              \
00529                                         : ISQ_save_label_bg );            \
00530       }else{                                                              \
00531          sprintf(sl,"Save.%.3s",ppmto_suffix[(seq)->opt.save_filter]) ;   \
00532       }                                                                   \
00533            if( (seq)->opt.save_agif ) strcpy(sl,"Sav:aGif") ;             \
00534       else if( (seq)->opt.save_mpeg ) strcpy(sl,"Sav:mpeg") ;             \
00535       else if( (seq)->opt.save_one  ) sl[3] = '1' ;                       \
00536       MCW_set_widget_label( (seq)->wbut_bot[NBUT_SAVE] , sl ) ; } while(0)
00537 
00538 static const ISQ_bdef ISQ_but_rig_def[NBUTTON_RIG] = {
00539      { "Colr" , ISQ_but_color_CB } ,
00540      { "Swap" , ISQ_but_cswap_CB } ,
00541      { "Norm" , ISQ_but_cnorm_CB }
00542 } ;
00543 
00544 
00545 
00546 static char * ISQ_but_bot_hint[NBUTTON_BOT] = {
00547    "Extra image controls" ,
00548    "Save images controls" ,
00549    "Image montage controls" ,
00550    "Close window"
00551 } ;
00552 
00553 static char * ISQ_but_bot_help[NBUTTON_BOT] = {
00554    "Pops up a window with options\n"
00555    "to control the image display\n"
00556    "and how the Save button works"   ,
00557 
00558    "Will popup control panels to let you save images from this window.\n"
00559    "The type of save operation is indicated on the button label, and\n"
00560    "is selected from the 'Disp' button options window.\n"
00561    " :bkg = Will save only the background image data values\n"
00562    "        (in a recorder window, the background image IS in color)\n"
00563    " :pnm = Will save the actual displayed focus image in color (PNM format)\n"
00564    "NOTES:\n"
00565    " * Saved images will NOT be stretched to match window resizing.\n"
00566    " * The PNM format requires the 'netpbm' package to be useful.\n"
00567    "    Alternatively, the 'xv' program will read/write PNM images." ,
00568 
00569    "Will popup a control box to let you\n"
00570    "display a montage of images, instead\n"
00571    "of just one image at a time.\n\n"
00572    "WARNING: this can be quite slow!"   ,
00573 
00574    "Closes this\n"
00575    "viewing window"
00576 } ;
00577 
00578 static char * ISQ_but_rig_help[NBUTTON_RIG] = {
00579    "Switches the colormap\nbetween False Color\nand Grayscale" ,
00580    "Swaps the colormap\nend for end" ,
00581    "Restores the colormap\nto its `normal' state"
00582 } ;
00583 
00584 static char * ISQ_but_rig_hint[NBUTTON_RIG] = {
00585    "Switch between color and gray" ,
00586    "Invert color/gray levels" ,
00587    "Return color/gray scale to normal"
00588 } ;
00589 
00590 static char * ISQ_scale_help =
00591   "Moves between images:\nDrag bar, or click in trough" ;
00592 
00593 static char * ISQ_default_image_help = "This is the image!" ;
00594 
00595 static char * ISQ_form_help =
00596      "************************************************\n"
00597      "* Image Sequence Display Module                *\n"
00598      "*                                              *\n"
00599      "* Copyright 1994, Medical College of Wisconsin *\n"
00600      "*          -2000  Milwaukee, WI 53226-0509     *\n"
00601      "* Released under the GPL (v2)                  *\n"
00602      "*                                              *\n"
00603      "* Author:  Robert W Cox, PhD                   *\n"
00604      "************************************************"   ;
00605 
00606 
00607 
00608 static char * ISQ_arrow_label[NARROW] = { "c" , "b" , "r" , "g" , "i" } ;
00609 
00610 #define NARR_SQUEEZE 0  
00611 #define NARR_BRIGHT  1
00612 #define NARR_ROTATE  2
00613 #define NARR_GAMMA   3
00614 #define NARR_FRAC    4
00615 
00616 static char * ISQ_arrow_help[NARROW] = {
00617    "Change constrast\nin colormap" ,
00618    "Change brightness\nin colormap" ,
00619    "Rotate\ncolormap" ,
00620    "Alter\ndisplay\ngamma" ,
00621    "Alter\nimage\nfraction\nin window"
00622 } ;
00623 
00624 static char * ISQ_arrow_hint[NARROW] = {
00625    "Contrast" ,
00626    "Brightness" ,
00627    "Rotate" ,
00628    "Gamma" ,
00629    "Image fraction"
00630 } ;
00631 
00632 
00633 
00634 #define DEFAULT_MINFRAC 0.02
00635 #define DEFAULT_MAXFRAC 0.90
00636 
00637 #define OPACITY_FAC  0.11111  
00638 #define OPACITY_BOT  0
00639 #define OPACITY_TOP  9
00640 
00641 #define ZOOM_BOT  1          
00642 #define ZOOM_TOP  4
00643 
00644 MCW_imseq * open_MCW_imseq( MCW_DC * dc ,
00645                             get_ptr get_image , XtPointer aux )
00646 {
00647    MCW_imseq        * newseq ;
00648    MCW_imseq_status * imstatus ;
00649    int ii , xwide , yhigh , one_image ;
00650    float fac ;
00651    MRI_IMAGE * tim ;
00652    float minfrac=DEFAULT_MINFRAC ; char * eee ; 
00653    Widget wtemp ;                               
00654    float maxfrac=DEFAULT_MAXFRAC ;              
00655 
00656 ENTRY("open_MCW_imseq") ;
00657 
00658 #define ERREX { myXtFree(newseq) ; XBell(dc->display,100) ; RETURN(NULL) ; }
00659 
00660    
00661 
00662    if( ppmto_num < 0 ){
00663       ISQ_setup_ppmto_filters() ;  
00664 
00665       if( ppmto_num > 0 ){         
00666 
00667          int nbut_old     = ISQ_dispbb[NTOG_SAV].nbut , qq,pp ;
00668          char ** lbut_old = ISQ_dispbb[NTOG_SAV].lbut ;
00669          char ** help_old = ISQ_bb_allhelp[NTOG_SAV] ;
00670          char ** hint_old = ISQ_bb_allhint[NTOG_SAV] ;
00671 
00672          ISQ_dispbb[NTOG_SAV].nbut += ppmto_num ;
00673          ISQ_dispbb[NTOG_SAV].lbut  = (char **) malloc(sizeof(char *)
00674                                                        *ISQ_dispbb[NTOG_SAV].nbut);
00675          for( qq=0 ; qq < nbut_old ; qq++ )
00676             ISQ_dispbb[NTOG_SAV].lbut[qq] = lbut_old[qq] ;
00677          for( pp=0 ; pp < ppmto_num ; pp++,qq++ ){
00678             ISQ_dispbb[NTOG_SAV].lbut[qq] = AFMALL( char, 32) ;
00679             sprintf(ISQ_dispbb[NTOG_SAV].lbut[qq] ,
00680                     "Save to .%.3s(s)" , ppmto_suffix[pp] ) ;
00681          }
00682 
00683          ISQ_bb_allhelp[NTOG_SAV] = (char **) malloc(sizeof(char *)
00684                                                      *ISQ_dispbb[NTOG_SAV].nbut);
00685          ISQ_bb_allhint[NTOG_SAV] = (char **) malloc(sizeof(char *)
00686                                                      *ISQ_dispbb[NTOG_SAV].nbut);
00687          for( qq=0 ; qq < nbut_old ; qq++ ){
00688             ISQ_bb_allhelp[NTOG_SAV][qq] = help_old[qq] ;
00689             ISQ_bb_allhint[NTOG_SAV][qq] = hint_old[qq] ;
00690          }
00691          for( pp=0 ; pp < ppmto_num ; pp++,qq++ )
00692             ISQ_bb_allhelp[NTOG_SAV][qq] = ISQ_bb_allhint[NTOG_SAV][qq] = NULL ;
00693       }
00694    }
00695 
00696    newseq = (MCW_imseq *) XtMalloc( sizeof(MCW_imseq) ) ;  
00697 
00698    newseq->dc     = dc ;               
00699    newseq->getim  = get_image ;
00700    newseq->getaux = aux ;
00701 
00702    newseq->never_drawn = 1 ;
00703 
00704 #if 0
00705    imstatus = (MCW_imseq_status *) get_image(0,isqCR_getstatus,aux) ;
00706 #else
00707    AFNI_CALL_VALU_3ARG( get_image , MCW_imseq_status *,imstatus ,
00708                         int,0 , int,isqCR_getstatus , XtPointer,aux ) ;
00709 #endif
00710    if( imstatus->num_total < 1 ){ ERREX ; }
00711    one_image = (imstatus->num_total == 1) ;
00712 
00713 #if 0
00714    tim = (MRI_IMAGE *) get_image(0,isqCR_getqimage,aux) ;  
00715 #else
00716    AFNI_CALL_VALU_3ARG( get_image , MRI_IMAGE *,tim ,
00717                         int,0 , int,isqCR_getqimage , XtPointer,aux ) ;
00718 #endif
00719 
00720    newseq->horig = tim->nx ;  
00721    newseq->vorig = tim->ny ;
00722 
00723    newseq->cropit       =  0 ; 
00724    newseq->crop_allowed =  1 ;
00725    newseq->crop_nxorg   = -1 ;
00726 
00727    newseq->last_width_mm  = IM_WIDTH(tim) ;  
00728    newseq->last_height_mm = IM_HEIGHT(tim) ;
00729 
00730    newseq->last_dx = newseq->last_dy = 1.0 ; 
00731    newseq->rgb_gamma  = 1.0 ;                
00732    newseq->rgb_offset = 0.0 ;
00733 
00734    fac = (newseq->last_width_mm  / newseq->horig)    
00735         /(newseq->last_height_mm / newseq->vorig) ;  
00736 
00737    if( fac >= 1.0 ){                                 
00738       xwide = newseq->horig * fac + 0.49 ;
00739       yhigh = newseq->vorig ;
00740    } else {
00741       xwide = newseq->horig ;
00742       yhigh = newseq->vorig / fac + 0.49 ;
00743    }
00744 
00745 if( PRINT_TRACING ){
00746   char str[256] ;
00747   sprintf(str,"nx=%d ny=%d dx=%f dy=%f wid=%f hei=%f xwide=%d yhigh=%d",
00748               tim->nx,tim->ny,tim->dx,tim->dy,newseq->last_width_mm,
00749               newseq->last_height_mm , xwide,yhigh ) ;
00750   STATUS(str);
00751 }
00752 
00753    KILL_1MRI(tim) ;  
00754 
00755    newseq->hbase  = newseq->hactual =
00756                     newseq->old_hact = xwide ;   
00757 
00758    newseq->vbase  = newseq->vactual =
00759                     newseq->old_vact = yhigh ;
00760 
00761    newseq->status = imstatus ;
00762    newseq->im_nr  = imstatus->num_total / 2 ;  
00763    newseq->scl    = 0.0 ;                      
00764    newseq->lev    = dc->ncol_im-1 ;            
00765    newseq->bot    = 0 ;
00766    newseq->top    = dc->ncol_im-1 ;
00767 
00768    newseq->clbot  = newseq->cltop  = 0.0 ;     
00769    newseq->barbot = newseq->bartop = 0.0 ;
00770 
00771    strcpy( newseq->im_label , "hi bob" ) ;
00772 
00773    
00774 
00775    ISQ_DEFAULT_OPT(newseq->opt) ;  
00776    if( ppmto_num > 0 ) newseq->opt.save_filter = 0 ;  
00777    newseq->opt.parent = (XtPointer) newseq ;
00778    newseq->old_opt    = newseq->opt ;         
00779 
00780    newseq->last_image_type = -1 ;     
00781 
00782    newseq->dialog         = NULL ;               
00783    newseq->num_bbox       = 0 ;
00784    newseq->dialog_starter = -1 ;
00785    newseq->dont_place_dialog = 0 ;         
00786 
00787    newseq->imim = newseq->ovim = NULL ;    
00788 
00789    newseq->orim      = NULL ;              
00790    newseq->set_orim  = 0 ;
00791    newseq->need_orim = 0 ;
00792 
00793    newseq->given_xim = newseq->sized_xim
00794                      = newseq->given_xbar
00795                      = newseq->sized_xbar = NULL ;
00796 
00797    
00798 
00799    newseq->button2_enabled  = 0 ;
00800    newseq->button2_active   = 0 ;
00801    newseq->button2_pixel    = dc->ovc->pixov_greenest ;
00802    newseq->button2_drawmode = BUTTON2_OPENPOLY ;
00803    newseq->button2_width    =  0 ;  
00804    newseq->wimage_width     = -1 ;
00805    newseq->wimage_height    = -1 ;
00806 
00807    newseq->cursor_state     = CURSOR_NORMAL ;   
00808 
00809    
00810 
00811    newseq->imstat = (ISQ_indiv_statistics *)
00812                     XtMalloc( sizeof(ISQ_indiv_statistics)
00813                               * imstatus->num_total ) ;
00814 
00815    newseq->glstat = (ISQ_glob_statistics * )
00816                     XtMalloc( sizeof(ISQ_glob_statistics) ) ;
00817 
00818    for( ii=0 ; ii < imstatus->num_total ; ii++ ){
00819      newseq->imstat[ii].one_done = newseq->imstat[ii].glob_done = False ;
00820      newseq->imstat[ii].parent   = (XtPointer) newseq ;
00821    }
00822 
00823    newseq->glstat->parent = (XtPointer) newseq ;
00824 
00825    for( ii=0 ; ii < NHISTOG ; ii++ )
00826       newseq->glstat->hist[ii] = 0 ;  
00827 
00828    newseq->glstat->mm_done =
00829      newseq->glstat->per_done = (newseq->status->num_series < 2 ) ;
00830 
00831 #ifdef AUTOMATE_STATISTICS
00832    if( newseq->glstat->mm_done ){
00833       newseq->glstat->worker = 0 ;
00834    } else {
00835       newseq->glstat->worker = XtAppAddWorkProc(
00836                                   newseq->dc->appcontext ,
00837                                   ISQ_statistics_WP , newseq ) ;
00838    }
00839 #else
00840    newseq->glstat->worker = 0 ;
00841 #endif
00842 
00843    
00844 
00845    newseq->image_frac = IMAGE_FRAC ;  
00846 
00847 
00848 
00849 
00850    eee = my_getenv("AFNI_IMAGE_MINFRAC") ;
00851    if( eee != NULL ){
00852       float fff=0.0 ;
00853       ii = sscanf(eee,"%f",&fff) ;
00854       if( ii > 0 && fff > 0.0 && fff <= 0.9 ) minfrac = fff ;
00855       else                                    minfrac = DEFAULT_MINFRAC ;
00856    }
00857 
00858    eee = my_getenv("AFNI_IMAGE_MAXFRAC") ;
00859    if( eee != NULL ){
00860       float fff=0.0 ;
00861       ii = sscanf(eee,"%f",&fff) ;
00862       if( ii > 0 && fff > 0.0 && fff <= 1.0 ) maxfrac = fff ;
00863       else                                    maxfrac = DEFAULT_MAXFRAC ;
00864    }
00865 
00866    { float xxx = newseq->hactual , yyy = newseq->vactual ;
00867      float fff = (xxx*yyy)/(dc->width*dc->height) , ggg ;
00868 
00869      
00870 
00871      if( fff < minfrac ){
00872        fff = sqrt(minfrac/fff); xxx *= fff; yyy *= fff;   
00873      }
00874 
00875      
00876 
00877      fff = ggg = 1.0 ;
00878      if( xxx >= maxfrac*dc->width ) fff = maxfrac*dc->width / xxx; 
00879      if( yyy >= maxfrac*dc->height) ggg = maxfrac*dc->height/ yyy; 
00880      fff = MIN(fff,ggg) ; xxx *= fff ; yyy *= fff ;
00881      if( xxx < 1.0 || yyy < 1.0 ){                     
00882        xxx = newseq->hactual ; yyy = newseq->vactual; 
00883      }
00884      xwide = (int) ( 0.49 + xxx / IMAGE_FRAC ) ;
00885      yhigh = (int) ( 0.49 + yyy / IMAGE_FRAC ) ;
00886 
00887      fff = ggg = 1.0 ;
00888      if( xwide >= maxfrac*dc->width ) fff = maxfrac*dc->width / xwide; 
00889      if( yhigh >= maxfrac*dc->height) ggg = maxfrac*dc->height/ yhigh; 
00890      fff = MIN(fff,ggg) ; xwide *= fff ; yhigh *= fff ;
00891    }
00892 
00893    
00894 
00895    newseq->onoff_num   = 0 ;
00896    newseq->onoff_state = 1 ;  
00897 
00898    
00899 
00900    newseq->wtop =
00901       XtVaAppCreateShell(
00902            "AFNI" , "AFNI" ,
00903            topLevelShellWidgetClass , dc->display ,
00904 
00905            XmNminAspectX , xwide ,      
00906            XmNminAspectY , yhigh ,
00907            XmNmaxAspectX , xwide ,
00908            XmNmaxAspectY , yhigh ,
00909 
00910            XmNmaxWidth   , dc->width ,  
00911            XmNmaxHeight  , dc->height ,
00912 
00913            XmNdeleteResponse , XmDO_NOTHING , 
00914 
00915            XmNallowShellResize , False ,       
00916 
00917            XmNinitialResourcesPersistent , False ,
00918       NULL ) ;
00919 
00920    DC_yokify( newseq->wtop , dc ) ;  
00921 
00922 #if 1
00923    if( MCW_isitmwm( newseq->wtop ) )
00924       XtVaSetValues( newseq->wtop ,
00925                         XmNmwmDecorations , MWM_DECOR_ALL | MWM_DECOR_MAXIMIZE ,
00926                      NULL ) ;
00927 #endif
00928 
00929    XmAddWMProtocolCallback(           
00930            newseq->wtop ,
00931            XmInternAtom( dc->display , "WM_DELETE_WINDOW" , False ) ,
00932            ISQ_but_done_CB , newseq ) ;
00933 
00934    newseq->done_first = True ;  
00935 
00936    
00937 
00938    newseq->wform =
00939       XtVaCreateWidget(
00940            "imseq" , xmFormWidgetClass , newseq->wtop ,
00941 
00942             XmNwidth  , xwide ,      
00943             XmNheight , yhigh ,
00944 
00945             XmNborderWidth , 0 ,
00946 
00947             XmNfractionBase , FORM_FRAC_BASE ,
00948 
00949             XmNhorizontalSpacing , 0 ,  
00950             XmNverticalSpacing   , 0 ,
00951 
00952             XmNtraversalOn , False ,
00953             XmNinitialResourcesPersistent , False ,
00954       NULL ) ;
00955 
00956    MCW_register_help( newseq->wform , ISQ_form_help ) ;
00957 
00958    
00959 
00960    newseq->wimage =
00961        XtVaCreateManagedWidget(
00962          "imseq" , xmDrawingAreaWidgetClass , newseq->wform ,
00963 
00964           XmNtopAttachment    , XmATTACH_FORM ,
00965           XmNleftAttachment   , XmATTACH_FORM ,
00966           XmNrightAttachment  , XmATTACH_POSITION ,
00967           XmNrightPosition    , (int)( 0.49 + IMAGE_FRAC * FORM_FRAC_BASE ) ,
00968           XmNbottomAttachment , XmATTACH_POSITION ,
00969           XmNbottomPosition   , (int)( 0.49 + IMAGE_FRAC * FORM_FRAC_BASE ) ,
00970 
00971           XmNtraversalOn , False ,
00972           XmNinitialResourcesPersistent , False ,
00973        NULL ) ;
00974 
00975    XtInsertEventHandler( newseq->wimage ,      
00976 
00977                             0
00978                           | KeyPressMask        
00979                           | ButtonPressMask     
00980                           | ExposureMask        
00981                           | StructureNotifyMask 
00982                           | Button1MotionMask   
00983                           | ButtonReleaseMask   
00984                          ,
00985                          FALSE ,                
00986                          ISQ_drawing_EV ,       
00987                          (XtPointer) newseq ,   
00988                          XtListTail ) ;         
00989 
00990    strcpy( newseq->im_helptext , ISQ_default_image_help ) ;
00991    newseq->im_helptext[ISQ_NHELP] = '\0' ;
00992 
00993    MCW_register_help( newseq->wimage , newseq->im_helptext ) ;
00994 
00995    
00996 
00997    for( ii=0 ; ii < NBUTTON_BOT ; ii++){
00998 
00999       Arg wa[30] ;
01000       int na ;
01001 
01002       na = 0 ;
01003 
01004       XtSetArg( wa[na] , XmNmarginWidth   , 1     ) ; na++ ;
01005       XtSetArg( wa[na] , XmNmarginHeight  , 0     ) ; na++ ;
01006       XtSetArg( wa[na] , XmNmarginBottom  , 0     ) ; na++ ;
01007       XtSetArg( wa[na] , XmNmarginTop     , 0     ) ; na++ ;
01008       XtSetArg( wa[na] , XmNmarginLeft    , 0     ) ; na++ ;
01009       XtSetArg( wa[na] , XmNmarginRight   , 0     ) ; na++ ;
01010       XtSetArg( wa[na] , XmNtraversalOn   , False ) ; na++ ;
01011       XtSetArg( wa[na] , XmNrecomputeSize , False ) ; na++ ;
01012 
01013       XtSetArg( wa[na] , XmNinitialResourcesPersistent , False ) ; na++ ;
01014 
01015       
01016 
01017       XtSetArg( wa[na] , EDGING_BOT , XmATTACH_FORM ) ; na++ ;
01018 
01019       if( ii == 0 ){  
01020 
01021          XtSetArg( wa[na] , LEADING_BOT , XmATTACH_FORM ) ; na++ ;
01022 
01023       } else if( ii == NBUTTON_BOT-1 ){  
01024 
01025          XtSetArg(wa[na],LEADING_BOT       ,XmATTACH_WIDGET)        ; na++ ;
01026          XtSetArg(wa[na],LEADING_WIDGET_BOT,newseq->wbut_bot[ii-1]) ; na++ ;
01027 
01028       } else {  
01029 
01030          XtSetArg(wa[na],LEADING_BOT       ,XmATTACH_WIDGET )       ; na++ ;
01031          XtSetArg(wa[na],LEADING_WIDGET_BOT,newseq->wbut_bot[ii-1] ); na++ ;
01032       }
01033 
01034       newseq->onoff_widgets[(newseq->onoff_num)++] =
01035       newseq->wbut_bot[ii] =
01036          XtCreateManagedWidget(
01037                ISQ_but_bot_def[ii].name ,
01038                xmPushButtonWidgetClass , newseq->wform ,
01039                wa , na ) ;
01040 
01041       if( ii == NBUT_DONE )   
01042          MCW_set_widget_bg( newseq->wbut_bot[ii] ,
01043                             MCW_hotcolor(newseq->wbut_bot[ii]) , 0 ) ;
01044 
01045       XtAddCallback( newseq->wbut_bot[ii] , XmNactivateCallback ,
01046                      ISQ_but_bot_def[ii].func_CB , newseq ) ;
01047 
01048       MCW_register_help( newseq->wbut_bot[ii] , ISQ_but_bot_help[ii] ) ;
01049       MCW_register_hint( newseq->wbut_bot[ii] , ISQ_but_bot_hint[ii] ) ;
01050    }
01051    SET_SAVE_LABEL(newseq) ;
01052 
01053    
01054 
01055    if( ppmto_num > 0 )
01056      XtInsertEventHandler( newseq->wbut_bot[NBUT_SAVE] ,
01057                            ButtonPressMask ,    
01058                            FALSE ,              
01059                            ISQ_butsave_EV ,     
01060                            (XtPointer) newseq , 
01061                            XtListTail           
01062                           ) ;
01063 
01064    
01065 
01066    ISQ_record_button( newseq ) ;
01067 
01068    
01069 
01070    for( ii=0 ; ii < NBUTTON_RIG ; ii++){
01071 
01072       Arg wa[30] ;
01073       int na ;
01074 
01075       na = 0 ;
01076 
01077       XtSetArg( wa[na] , XmNmarginWidth   , 1     ) ; na++ ;
01078       XtSetArg( wa[na] , XmNmarginHeight  , 0     ) ; na++ ;
01079       XtSetArg( wa[na] , XmNmarginBottom  , 0     ) ; na++ ;
01080       XtSetArg( wa[na] , XmNmarginTop     , 0     ) ; na++ ;
01081       XtSetArg( wa[na] , XmNmarginLeft    , 0     ) ; na++ ;
01082       XtSetArg( wa[na] , XmNmarginRight   , 0     ) ; na++ ;
01083       XtSetArg( wa[na] , XmNtraversalOn   , False ) ; na++ ;
01084       XtSetArg( wa[na] , XmNrecomputeSize , False ) ; na++ ;
01085 
01086       XtSetArg( wa[na] , XmNinitialResourcesPersistent , False ) ; na++ ;
01087 
01088       
01089 
01090       XtSetArg( wa[na] , EDGING_RIG , XmATTACH_FORM ) ; na++ ;
01091 
01092       if( ii == 0 ){  
01093 
01094          XtSetArg( wa[na] , LEADING_RIG , XmATTACH_FORM ) ; na++ ;
01095 
01096       } else {  
01097 
01098          XtSetArg(wa[na],LEADING_RIG       ,XmATTACH_WIDGET        ); na++ ;
01099          XtSetArg(wa[na],LEADING_WIDGET_RIG,newseq->wbut_rig[ii-1] ); na++ ;
01100       }
01101 
01102       newseq->onoff_widgets[(newseq->onoff_num)++] =
01103       newseq->wbut_rig[ii] =
01104          XtCreateManagedWidget(
01105                ISQ_but_rig_def[ii].name ,
01106                xmPushButtonWidgetClass , newseq->wform ,
01107                wa , na ) ;
01108 
01109       XtAddCallback( newseq->wbut_rig[ii] , XmNactivateCallback ,
01110                      ISQ_but_rig_def[ii].func_CB , newseq ) ;
01111 
01112       MCW_register_help( newseq->wbut_rig[ii] , ISQ_but_rig_help[ii] ) ;
01113       MCW_register_hint( newseq->wbut_rig[ii] , ISQ_but_rig_hint[ii] ) ;
01114    }
01115 
01116    
01117 
01118    for( ii=0 ; ii < NARROW ; ii++ ){
01119 
01120       newseq->arrow[ii] = new_MCW_arrowval(
01121                              newseq->wform , ISQ_arrow_label[ii] ,
01122                              MCW_AV_downup , 0,0,0 ,
01123                              MCW_AV_notext , 0 ,
01124                              ISQ_arrow_CB , (XtPointer) newseq ,
01125                              NULL,NULL ) ;
01126 
01127       newseq->onoff_widgets[(newseq->onoff_num)++] = newseq->arrow[ii]->wrowcol ;
01128 
01129       XtVaSetValues( newseq->arrow[ii]->wrowcol ,
01130                         EDGING_RIG   , XmATTACH_FORM ,
01131                         LEADING_RIG  , XmATTACH_WIDGET ,
01132 
01133                         LEADING_WIDGET_RIG ,
01134                            (ii==0) ? (newseq->wbut_rig[NBUTTON_RIG-1])
01135                                    : (newseq->arrow[ii-1]->wrowcol) ,
01136                      NULL ) ;
01137 
01138       if( ii != NARR_FRAC )
01139          newseq->arrow[ii]->fastdelay = 10 ;                 
01140       newseq->arrow[ii]->parent       = (XtPointer) newseq ; 
01141 
01142       MCW_reghelp_children( newseq->arrow[ii]->wrowcol, ISQ_arrow_help[ii] );
01143       MCW_reghint_children( newseq->arrow[ii]->wrowcol, ISQ_arrow_hint[ii] );
01144    }
01145 
01146 
01147 
01148    wtemp = newseq->arrow[NARROW-1]->wrowcol ;  
01149 
01150    newseq->ov_opacity = 1.0 ;  
01151 
01152    if( newseq->dc->visual_class == TrueColor ){
01153      int iov = (int)rint(newseq->ov_opacity/OPACITY_FAC) ;
01154      char * buf = ISQ_opacity_label(iov) ;
01155 
01156 
01157 
01158      newseq->ov_opacity_sep = XtVaCreateManagedWidget(
01159                                 "imseq" , xmSeparatorWidgetClass , newseq->wform ,
01160                                    XmNseparatorType , XmSINGLE_LINE ,
01161                                    EDGING_RIG   , XmATTACH_FORM ,
01162                                    LEADING_RIG  , XmATTACH_WIDGET ,
01163                                    LEADING_WIDGET_RIG , wtemp ,
01164                                    XmNleftAttachment , XmATTACH_OPPOSITE_WIDGET ,
01165                                    XmNleftWidget , wtemp ,
01166                                    XmNleftOffset , 7 ,
01167                                 NULL ) ;
01168      newseq->onoff_widgets[(newseq->onoff_num)++] = newseq->ov_opacity_sep ;
01169 
01170      newseq->ov_opacity_av = new_MCW_arrowval(
01171                                newseq->wform ,        
01172                                buf ,                  
01173                                MCW_AV_downup ,        
01174                                OPACITY_BOT ,          
01175                                OPACITY_TOP ,          
01176                                iov ,                  
01177                                MCW_AV_notext ,        
01178                                0 ,                    
01179                                ISQ_opacity_CB ,       
01180                                (XtPointer) newseq ,   
01181                                NULL ,                 
01182                                NULL                   
01183                              ) ;
01184 
01185      newseq->ov_opacity_av->parent = (XtPointer) newseq ;
01186      newseq->onoff_widgets[(newseq->onoff_num)++] = newseq->ov_opacity_av->wrowcol ;
01187 
01188      XtVaSetValues( newseq->ov_opacity_av->wrowcol ,
01189                       EDGING_RIG   , XmATTACH_FORM ,
01190                       LEADING_RIG  , XmATTACH_WIDGET ,
01191                       LEADING_WIDGET_RIG , newseq->ov_opacity_sep ,
01192                     NULL ) ;
01193 
01194      wtemp = newseq->ov_opacity_av->wrowcol ; 
01195 
01196      MCW_reghelp_children( newseq->ov_opacity_av->wrowcol,
01197                            "Controls the opacity\n"
01198                            "of the color overlay:\n"
01199                            "  1 = barely visible  \n"
01200                            "  9 = totally opaque"   ) ;
01201      MCW_reghint_children( newseq->ov_opacity_av->wrowcol, "Color overlay opacity" );
01202 
01203    } else {
01204      newseq->ov_opacity_av  = NULL ;
01205      newseq->ov_opacity_sep = NULL ;
01206    }
01207 
01208      newseq->zoom_sep = XtVaCreateManagedWidget(
01209                          "imseq" , xmSeparatorWidgetClass , newseq->wform ,
01210                             XmNseparatorType , XmSINGLE_LINE ,
01211                             EDGING_RIG   , XmATTACH_FORM ,
01212                             LEADING_RIG  , XmATTACH_WIDGET ,
01213                             LEADING_WIDGET_RIG , wtemp ,
01214                             XmNleftAttachment , XmATTACH_OPPOSITE_WIDGET ,
01215                             XmNleftWidget , wtemp ,
01216                             XmNleftOffset , 7 ,
01217                          NULL ) ;
01218      newseq->onoff_widgets[(newseq->onoff_num)++] = newseq->zoom_sep ;
01219 
01220      newseq->zoom_val_av = new_MCW_arrowval(
01221                                newseq->wform ,        
01222                                "z" ,                  
01223                                MCW_AV_downup ,        
01224                                ZOOM_BOT ,             
01225                                ZOOM_TOP ,             
01226                                ZOOM_BOT ,             
01227                                MCW_AV_notext ,        
01228                                0 ,                    
01229                                ISQ_zoom_av_CB ,       
01230                                (XtPointer) newseq ,   
01231                                NULL ,                 
01232                                NULL                   
01233                              ) ;
01234      newseq->zoom_val_av->parent = (XtPointer) newseq ;
01235      newseq->onoff_widgets[(newseq->onoff_num)++] = newseq->zoom_val_av->wrowcol ;
01236      XtVaSetValues( newseq->zoom_val_av->wrowcol ,
01237                       EDGING_RIG   , XmATTACH_FORM ,
01238                       LEADING_RIG  , XmATTACH_WIDGET ,
01239                       LEADING_WIDGET_RIG , newseq->zoom_sep ,
01240                     NULL ) ;
01241      MCW_reghelp_children( newseq->zoom_val_av->wrowcol,
01242                            "- Images can be zoomed in by\n"
01243                            "   a factor of 2, 3, or 4.\n"
01244                            "- These 'Z' buttons change\n"
01245                            "   the zoom factor up and down.\n"
01246                            "- Panning the zoomed image is\n"
01247                            "   done by pressing the 'pan'\n"
01248                            "   button and then clicking and\n"
01249                            "   dragging with Button #1 down\n\n"
01250                            "**WARNING: zooming in by 4 can\n"
01251                            "   consume so much memory that\n"
01252                            "   AFNI or the X11 server will\n"
01253                            "   crash.  If this happens, then\n"
01254                            "   avoid zooming that much (duh).\n" ) ;
01255      MCW_reghint_children( newseq->zoom_val_av->wrowcol, "Image zoom factor" );
01256      AV_SENSITIZE_DOWN( newseq->zoom_val_av , False ) ;
01257 
01258      newseq->zoom_drag_pb =
01259         XtVaCreateManagedWidget(
01260            "imseq" , xmPushButtonWidgetClass , newseq->wform ,
01261             LABEL_ARG("pan") ,
01262             XmNmarginWidth   , 1 ,
01263             XmNmarginHeight  , 0 ,
01264             XmNmarginBottom  , 0 ,
01265             XmNmarginTop     , 0 ,
01266             XmNmarginLeft    , 0 ,
01267             XmNmarginRight   , 0 ,
01268             XmNtraversalOn , False ,
01269             XmNinitialResourcesPersistent , False ,
01270          NULL ) ;
01271      XtAddCallback( newseq->zoom_drag_pb , XmNactivateCallback ,
01272                     ISQ_zoom_pb_CB , newseq ) ;
01273 
01274      newseq->onoff_widgets[(newseq->onoff_num)++] = newseq->zoom_drag_pb ;
01275 
01276      XtVaSetValues( newseq->zoom_drag_pb ,
01277                       EDGING_RIG   , XmATTACH_FORM ,
01278                       LEADING_RIG  , XmATTACH_WIDGET ,
01279                       LEADING_WIDGET_RIG , newseq->zoom_val_av->wrowcol ,
01280                   NULL ) ;
01281 
01282      MCW_register_help( newseq->zoom_drag_pb ,
01283                            "To pan the zoomed image window:\n"
01284                            "- Click on this 'pan' button\n"
01285                            "- Then drag the image with mouse\n"
01286                            "   Button #1 (the cursor in the\n"
01287                            "   image window will be hand-shaped)\n"
01288                            "- When you finish dragging, panning\n"
01289                            "   mode will be turned off\n"
01290                            "- If you want panning mode to stay\n"
01291                            "   turned on until you click 'pan'\n"
01292                            "   again, set environment variable\n"
01293                            "   AFNI_KEEP_PANNING to YES"         ) ;
01294      MCW_register_hint( newseq->zoom_drag_pb ,
01295                            "Pan zoomed image" );
01296 
01297      SENSITIZE( newseq->zoom_drag_pb , 0 ) ;
01298 
01299      wtemp = newseq->zoom_drag_pb ;
01300 
01301      newseq->zoom_fac     = 1   ;     
01302      newseq->zoom_hor_off = 0.0 ;
01303      newseq->zoom_ver_off = 0.0 ;
01304      newseq->zoom_pixmap  = (Pixmap) 0 ;
01305      newseq->zoom_pw      = 0 ;
01306      newseq->zoom_ph      = 0 ;
01307      newseq->zoom_xim     = NULL ;
01308      newseq->zoom_button1 = 0 ;       
01309 
01310      
01311 
01312      newseq->crop_drag_pb =
01313         XtVaCreateManagedWidget(
01314            "imseq" , xmPushButtonWidgetClass , newseq->wform ,
01315             LABEL_ARG("crop") ,
01316             XmNmarginWidth   , 1 ,
01317             XmNmarginHeight  , 0 ,
01318             XmNmarginBottom  , 0 ,
01319             XmNmarginTop     , 0 ,
01320             XmNmarginLeft    , 0 ,
01321             XmNmarginRight   , 0 ,
01322             XmNtraversalOn , False ,
01323             XmNinitialResourcesPersistent , False ,
01324          NULL ) ;
01325      XtAddCallback( newseq->crop_drag_pb , XmNactivateCallback ,
01326                     ISQ_crop_pb_CB , newseq ) ;
01327      newseq->crop_drag = 0 ;
01328 
01329      newseq->onoff_widgets[(newseq->onoff_num)++] = newseq->crop_drag_pb ;
01330 
01331      XtVaSetValues( newseq->crop_drag_pb ,
01332                       EDGING_RIG   , XmATTACH_FORM ,
01333                       LEADING_RIG  , XmATTACH_WIDGET ,
01334                       LEADING_WIDGET_RIG , wtemp ,
01335                   NULL ) ;
01336 
01337      MCW_register_help( newseq->crop_drag_pb ,
01338                            "To crop the image window:\n"
01339                            "- Click on this 'crop' button;\n"
01340                            "- Then click and hold down a\n"
01341                            "   mouse Button at a corner\n"
01342                            "   of the rectangle to crop;\n"
01343                            "- Then drag a rectangle to crop\n"
01344                            "   and release the mouse button\n"
01345                            "\n"
01346                            "To uncrop (back to original size):\n"
01347                            "- Click on this 'crop' button\n"
01348                            "- Click on it again without cropping\n"
01349                            "\n"
01350                            "Another way to crop without using\n"
01351                            "this 'crop' button is to drag the\n"
01352                            "crop rectangle using Shift+Button #2\n"
01353                            "\n"
01354                            "Another way to uncrop is to click\n"
01355                            "Shift+Button #2 in the image without\n"
01356                            "any dragging\n"
01357                        ) ;
01358      MCW_register_hint( newseq->crop_drag_pb ,
01359                            "Crop image" );
01360 
01361      wtemp = newseq->crop_drag_pb ;
01362 
01363    
01364 
01365    { char *lbl = "pen" ;
01366      newseq->pen_bbox = new_MCW_bbox( newseq->wform ,
01367                                       1 , &lbl ,
01368                                       MCW_BB_check , MCW_BB_noframe ,
01369                                       ISQ_pen_bbox_CB , (XtPointer)newseq ) ;
01370 
01371      newseq->onoff_widgets[(newseq->onoff_num)++] = newseq->pen_bbox->wrowcol ;
01372 
01373      XtVaSetValues( newseq->pen_bbox->wrowcol ,
01374                       EDGING_RIG   , XmATTACH_FORM ,
01375                       LEADING_RIG  , XmATTACH_WIDGET ,
01376                       LEADING_WIDGET_RIG , wtemp ,
01377                   NULL ) ;
01378 
01379      MCW_reghelp_children( newseq->pen_bbox->wrowcol ,
01380                            "In ROI drawing mode, toggles\n"
01381                            "the cursor to a pen shape,\n"
01382                            "and turn on drawing with\n"
01383                            "mouse Button-1."
01384                          ) ;
01385      MCW_reghint_children( newseq->pen_bbox->wrowcol ,
01386                            "Toggle pen drawing" ) ;
01387 
01388      XtUnmanageChild( newseq->pen_bbox->wrowcol ) ;
01389      wtemp = newseq->pen_bbox->wrowcol ;
01390    }
01391 
01392    
01393 
01394    ii = (one_image) ? 1 : newseq->status->num_total - 1 ;
01395 
01396    newseq->onoff_widgets[(newseq->onoff_num)++] =
01397    newseq->wscale =
01398        XtVaCreateManagedWidget(
01399           "imseq" , xmScaleWidgetClass , newseq->wform ,
01400 
01401           XmNtopAttachment    , XmATTACH_WIDGET ,
01402           XmNtopWidget        , newseq->wimage ,
01403           XmNleftAttachment   , XmATTACH_FORM ,
01404           XmNrightAttachment  , XmATTACH_POSITION ,
01405           XmNrightPosition    , (int)( 0.49 + IMAGE_FRAC * FORM_FRAC_BASE ),
01406 
01407           XmNminimum       , 0 ,                       
01408           XmNmaximum       , ii ,
01409           XmNvalue         , newseq->im_nr ,           
01410           XmNshowValue     , True ,                    
01411           XmNscaleMultiple , 1 ,                       
01412           XmNorientation   , XmHORIZONTAL ,            
01413 
01414           XmNtraversalOn , False ,
01415           XmNinitialResourcesPersistent , False ,
01416        NULL ) ;
01417 
01418    XtAddCallback( newseq->wscale , XmNvalueChangedCallback ,
01419                   ISQ_scale_CB , newseq ) ;
01420 
01421    MCW_reghelp_children( newseq->wscale , ISQ_scale_help ) ;
01422 #if 0
01423    MCW_register_hint( newseq->wscale , "Moves between images" ) ;
01424 #endif
01425 
01426    
01427 
01428    newseq->arrowpad = new_MCW_arrowpad(
01429                            newseq->wform ,
01430                            ISQ_arrowpad_CB , (XtPointer) newseq ) ;
01431 
01432    newseq->onoff_widgets[(newseq->onoff_num)++] = newseq->arrowpad->wform ;
01433 
01434    XtVaSetValues( newseq->arrowpad->wform ,
01435                      XmNbottomAttachment , XmATTACH_FORM ,
01436                      XmNrightAttachment  , XmATTACH_FORM ,
01437                      XtNmappedWhenManaged , False ,   
01438                   NULL ) ;
01439 
01440    newseq->arrowpad->parent = (XtPointer) newseq ;
01441 
01442    
01443 
01444    newseq->onoff_widgets[(newseq->onoff_num)++] =
01445    newseq->wbar =
01446        XtVaCreateManagedWidget(
01447           "imseq" , xmDrawingAreaWidgetClass , newseq->wform ,
01448 
01449            XmNtopAttachment    , XmATTACH_FORM ,
01450            XmNleftAttachment   , XmATTACH_WIDGET ,
01451            XmNleftWidget       , newseq->wimage ,
01452            XmNleftOffset       , COLOR_BAR_SPACE ,
01453            XmNbottomAttachment , XmATTACH_POSITION ,
01454            XmNbottomPosition   , (int)( 0.49 + IMAGE_FRAC * FORM_FRAC_BASE ),
01455 
01456            XmNwidth       , COLOR_BAR_WIDTH ,
01457 
01458            XmNtraversalOn , False ,
01459            XmNinitialResourcesPersistent , False ,
01460        NULL ) ;
01461 
01462    XtInsertEventHandler( newseq->wbar ,          
01463 
01464                             0
01465                           | ButtonPressMask      
01466                           | ExposureMask         
01467                           | StructureNotifyMask  
01468                          ,
01469                          FALSE ,                 
01470                          ISQ_drawing_EV ,        
01471                          (XtPointer) newseq ,    
01472                          XtListTail ) ;          
01473 
01474    
01475 
01476    MCW_register_help( newseq->wbar ,
01477                       "Use Button 3 to popup\n"
01478                       "a display control menu\n"
01479                       "\n"
01480                       "Use Button 1 to enforce\n"
01481                       "image aspect ratio"       ) ;
01482 
01483 #ifdef BAD_BUTTON3_POPUPS   
01484    newseq->wbar_menu = XmCreatePopupMenu( newseq->wscale, "menu",NULL,0 ) ;
01485 #else
01486    newseq->wbar_menu = XmCreatePopupMenu( newseq->wbar  , "menu",NULL,0 ) ;
01487 #endif
01488 
01489    SAVEUNDERIZE(XtParent(newseq->wbar_menu)) ;  
01490 
01491    VISIBILIZE_WHEN_MAPPED(newseq->wbar_menu) ;
01492 
01493    newseq->wbar_rng_but =
01494       XtVaCreateManagedWidget(
01495          "menu" , xmPushButtonWidgetClass , newseq->wbar_menu ,
01496             LABEL_ARG("Choose Display Range") ,
01497             XmNtraversalOn , False ,
01498             XmNinitialResourcesPersistent , False ,
01499          NULL ) ;
01500 
01501    XtAddCallback( newseq->wbar_rng_but, XmNactivateCallback, ISQ_wbar_menu_CB, newseq ) ;
01502 
01503    newseq->wbar_zer_but =
01504       XtVaCreateManagedWidget(
01505          "menu" , xmPushButtonWidgetClass , newseq->wbar_menu ,
01506             LABEL_ARG("Choose Zero Color") ,
01507             XmNtraversalOn , False ,
01508             XmNinitialResourcesPersistent , False ,
01509          NULL ) ;
01510 
01511    XtAddCallback( newseq->wbar_zer_but, XmNactivateCallback, ISQ_wbar_menu_CB, newseq ) ;
01512 
01513    newseq->wbar_flat_but =
01514       XtVaCreateManagedWidget(
01515          "menu" , xmPushButtonWidgetClass , newseq->wbar_menu ,
01516             LABEL_ARG("Choose Flatten Range") ,
01517             XmNtraversalOn , False ,
01518             XmNinitialResourcesPersistent , False ,
01519          NULL ) ;
01520 
01521    XtAddCallback( newseq->wbar_flat_but, XmNactivateCallback, ISQ_wbar_menu_CB, newseq ) ;
01522 
01523    newseq->wbar_sharp_but =
01524       XtVaCreateManagedWidget(
01525          "menu" , xmPushButtonWidgetClass , newseq->wbar_menu ,
01526             LABEL_ARG("Choose Sharpen factor") ,
01527             XmNtraversalOn , False ,
01528             XmNinitialResourcesPersistent , False ,
01529          NULL ) ;
01530 
01531    XtAddCallback( newseq->wbar_sharp_but, XmNactivateCallback, ISQ_wbar_menu_CB, newseq ) ;
01532 
01533    newseq->rng_bot   = newseq->rng_top = newseq->rng_ztop = 0 ;
01534    newseq->flat_bot  = newseq->flat_top = 0.0 ;
01535    newseq->sharp_fac = 0.60 ;
01536 
01537    newseq->zer_color = 0 ;
01538    ii = DC_find_overlay_color( newseq->dc , getenv("AFNI_IMAGE_ZEROCOLOR") ) ;
01539    if( ii > 0 ) newseq->zer_color = ii ;
01540 
01541    
01542 
01543    newseq->onoff_widgets[(newseq->onoff_num)++] =
01544    newseq->winfo = XtVaCreateManagedWidget(
01545                      "imseq" , xmLabelWidgetClass , newseq->wform ,
01546                         XmNtopAttachment   , XmATTACH_WIDGET ,
01547                         XmNtopWidget       , newseq->wscale ,
01548                         XmNleftAttachment  , XmATTACH_FORM ,
01549                         XmNrightAttachment , XmATTACH_POSITION ,
01550                         XmNrightPosition   ,
01551                             (int)( 0.49 + IMAGE_FRAC * FORM_FRAC_BASE ) ,
01552                         XmNrecomputeSize   , False ,
01553                         XmNalignment       , XmALIGNMENT_END ,
01554 
01555                         XmNinitialResourcesPersistent , False ,
01556                      NULL ) ;
01557    newseq->winfo_extra[0] = '\0' ;  
01558 
01559    newseq->winfo_sides[0][0] =
01560     newseq->winfo_sides[1][0] =
01561      newseq->winfo_sides[2][0] =
01562       newseq->winfo_sides[3][0] = '\0' ; 
01563 
01564    
01565 
01566    newseq->mont_across_av   = NULL ;
01567    newseq->mont_down_av     = NULL ;
01568    newseq->mont_skip_av     = NULL ;
01569    newseq->mont_gap_av      = NULL ;
01570    newseq->mont_gapcolor_av = NULL ;
01571 
01572    newseq->mont_nx       = newseq->mont_nx_old       = 1 ;
01573    newseq->mont_ny       = newseq->mont_ny_old       = 1 ;
01574    newseq->mont_skip     = newseq->mont_skip_old     = 0 ;
01575    newseq->mont_gap      = newseq->mont_gap_old      = 0 ;
01576    newseq->mont_gapcolor = newseq->mont_gapcolor_old = 0 ;
01577    newseq->mont_periodic = 1 ;                             
01578 
01579 STATUS("creation: widgets created") ;
01580 
01581    XtManageChild( newseq->wform ) ;
01582 
01583 #if 0
01584    XtRealizeWidget( newseq->wtop ) ;
01585    newseq->valid = 2 ;  
01586 
01587    NORMAL_cursorize( newseq->wtop ) ;
01588 
01589 #else
01590    newseq->valid = 1 ;  
01591 #endif
01592 
01593    newseq->ignore_redraws = 0 ;
01594 
01595    
01596 
01597    newseq->transform0D_func  = NULL ;  
01598    newseq->transform0D_av    = NULL ;
01599    newseq->transform0D_index = 0 ;
01600 
01601    newseq->transform2D_func  = NULL ;  
01602    newseq->transform2D_av    = NULL ;
01603    newseq->transform2D_index = 0 ;
01604 
01605    newseq->slice_proj_av       = NULL ;  
01606    newseq->slice_proj_func     = NULL ;
01607    newseq->slice_proj_index    = 0    ;
01608    newseq->slice_proj_range_av = NULL ;
01609    newseq->slice_proj_range    = 0    ;
01610 
01611    newseq->rowgraph_av  = NULL ;       
01612    newseq->rowgraph_num = 0 ;
01613    newseq->rowgraph_mtd = NULL ;
01614 
01615    newseq->graymap_mtd  = NULL ;       
01616    newseq->cmap_changed = 0 ;
01617 
01618 #define DEFAULT_THETA  55.0
01619 #define DEFAULT_PHI   285.0
01620 
01621    newseq->surfgraph_av    = NULL ;    
01622    newseq->surfgraph_num   = 0    ;
01623    newseq->surfgraph_mtd   = NULL ;
01624    newseq->surfgraph_theta = DEFAULT_THETA ;
01625    newseq->surfgraph_phi   = DEFAULT_PHI   ;
01626    newseq->surfgraph_arrowpad = NULL ;
01627 
01628    newseq->mplot = NULL ;              
01629 
01630    
01631 
01632 
01633    { static char *plabel[1] = { "Plot Overlay Plots" } ;
01634      static char *alabel[7] = { "Off", "UpperLeft", "UpperRight",
01635                                        "LowerLeft", "LowerRight",
01636                                        "UpperMid" , "LowerMid"   } ;
01637      static char *slabel[5] = { "Small" , "Medium" , "Large" , "Huge" , "Enormous" } ;
01638      char *eee ; int iii ;
01639 
01640      (void) XtVaCreateManagedWidget( "menu",
01641                                      xmSeparatorWidgetClass, newseq->wbar_menu,
01642                                        XmNseparatorType , XmSINGLE_LINE ,
01643                                      NULL ) ;
01644 
01645      
01646 
01647      newseq->wbar_plots_bbox = new_MCW_bbox( newseq->wbar_menu ,
01648                                              1 , plabel ,
01649                                              MCW_BB_check , MCW_BB_noframe ,
01650                                              ISQ_wbar_plots_CB , (XtPointer)newseq ) ;
01651      MCW_set_bbox( newseq->wbar_plots_bbox , 1 ) ;
01652 
01653      newseq->wbar_graymap_pb =
01654         XtVaCreateManagedWidget(
01655            "menu" , xmPushButtonWidgetClass , newseq->wbar_menu ,
01656               LABEL_ARG("Display Graymap Plot") ,
01657               XmNtraversalOn , False ,
01658               XmNinitialResourcesPersistent , False ,
01659            NULL ) ;
01660      XtAddCallback( newseq->wbar_graymap_pb, XmNactivateCallback, ISQ_wbar_menu_CB, newseq ) ;
01661 
01662      (void) XtVaCreateManagedWidget( "menu",
01663                                      xmSeparatorWidgetClass, newseq->wbar_menu,
01664                                        XmNseparatorType , XmSINGLE_LINE ,
01665                                      NULL ) ;
01666 
01667      newseq->timer_id = 0 ;  
01668 
01669      
01670 
01671      iii = 0 ;
01672      eee = getenv("AFNI_IMAGE_LABEL_MODE") ;
01673      if( eee != NULL ){
01674        iii = strtol(eee,NULL,10) ; if( iii < 0 || iii > 6 ) iii = 1 ;
01675      }
01676      newseq->wbar_label_av =
01677         new_MCW_arrowval( newseq->wbar_menu ,
01678                           "Label" ,
01679                           MCW_AV_optmenu ,      
01680                           0 ,                   
01681                           6 ,                   
01682                           iii ,                 
01683                           MCW_AV_readtext ,     
01684                           0 ,                   
01685                           ISQ_wbar_label_CB ,   
01686                           (XtPointer)newseq ,   
01687                           MCW_av_substring_CB , 
01688                           alabel                
01689                         ) ;
01690 
01691      iii = 1 ;
01692      eee = getenv("AFNI_IMAGE_LABEL_SIZE") ;
01693      if( eee != NULL ){
01694         iii = strtol(eee,NULL,10) ; if( iii < 0 || iii > 4 ) iii = 2 ;
01695      }
01696      newseq->wbar_labsz_av =
01697         new_MCW_arrowval( newseq->wbar_menu ,
01698                           "Size " ,
01699                           MCW_AV_optmenu ,      
01700                           0 ,                   
01701                           4 ,                   
01702                           iii ,                 
01703                           MCW_AV_readtext ,     
01704                           0 ,                   
01705                           ISQ_wbar_label_CB ,   
01706                           (XtPointer)newseq ,   
01707                           MCW_av_substring_CB , 
01708                           slabel                
01709                         ) ;
01710 
01711    } 
01712 
01713 
01714 
01715    (void) XtVaCreateManagedWidget( "menu",
01716                                    xmSeparatorWidgetClass, newseq->wbar_menu,
01717                                      XmNseparatorType , XmSINGLE_LINE ,
01718                                    NULL ) ;
01719    newseq->wbar_ticnum_av =
01720       new_MCW_arrowval( newseq->wbar_menu ,
01721                         "Tick Div." ,
01722                         MCW_AV_optmenu ,      
01723                         0 ,                   
01724                         20 ,                  
01725                         0 ,                   
01726                         MCW_AV_readtext ,     
01727                         0 ,                   
01728                         ISQ_wbar_label_CB ,   
01729                         (XtPointer)newseq ,   
01730                         NULL                , 
01731                         NULL                  
01732                       ) ;
01733    AVOPT_columnize(newseq->wbar_ticnum_av,2) ;
01734    MCW_reghint_children( newseq->wbar_ticnum_av->wrowcol ,
01735                          "Number of tick mark divisions on image edges" ) ;
01736    newseq->wbar_ticsiz_av =
01737       new_MCW_arrowval( newseq->wbar_menu ,
01738                         "Tick Size" ,
01739                         MCW_AV_optmenu ,      
01740                         1 ,                   
01741                         10 ,                  
01742                         1 ,                   
01743                         MCW_AV_readtext ,     
01744                         0 ,                   
01745                         ISQ_wbar_label_CB ,   
01746                         (XtPointer)newseq ,   
01747                         NULL                , 
01748                         NULL                  
01749                       ) ;
01750    AVOPT_columnize(newseq->wbar_ticsiz_av,2) ;
01751    MCW_reghint_children( newseq->wbar_ticsiz_av->wrowcol ,
01752                          "Size of tick marks around image edges" ) ;
01753 
01754    
01755 
01756    drive_MCW_imseq( newseq , isqDR_setimsave ,
01757                     (XtPointer)getenv("AFNI_DEFAULT_IMSAVE") ) ;
01758 
01759    
01760 
01761    { char *eee = getenv("AFNI_DEFAULT_OPACITY") ;
01762      if( eee != NULL ){
01763        int opval = (int) strtod( eee , NULL ) ;
01764        if( opval > 0 && opval <= 9 )
01765          drive_MCW_imseq( newseq , isqDR_setopacity , (XtPointer)opval ) ;
01766      }
01767    }
01768 
01769    newseq->parent = NULL ;
01770    RETURN(newseq) ;
01771 }
01772 
01773 
01774 
01775 
01776 
01777 
01778 
01779 
01780 void ISQ_reset_dimen( MCW_imseq * seq,  float new_width_mm, float new_height_mm )
01781 {
01782    int xwide , yhigh , oldx,oldy ;
01783    float scale_x , scale_y ;
01784    int wx,hy,xx,yy ;   
01785    int xp,yp ;
01786    MCW_DC *dc ;
01787 
01788    float minfrac=DEFAULT_MINFRAC ; char *eee ; 
01789    float maxfrac=DEFAULT_MAXFRAC ;
01790 
01791 ENTRY("ISQ_reset_dimen") ;
01792 
01793    if( ! ISQ_VALID(seq) ) EXRETURN ;
01794 
01795    MCW_widget_geom( seq->wimage , &oldx , &oldy , NULL,NULL ) ;
01796 
01797    scale_x = seq->last_width_mm / oldx ;  
01798    scale_y = seq->last_height_mm/ oldy ;
01799 
01800    if( ! seq->opt.free_aspect ){                      
01801       scale_x = scale_y = sqrt( scale_x * scale_y ) ; 
01802    }                                                  
01803 
01804    xwide = new_width_mm / scale_x + 0.5 ;  
01805    yhigh = new_height_mm/ scale_y + 0.5 ;
01806 
01807 
01808 
01809 
01810    eee = my_getenv("AFNI_IMAGE_MINFRAC") ;
01811    if( eee != NULL ){
01812       float fff=0.0 ; int ii ;
01813       ii = sscanf(eee,"%f",&fff) ;
01814       if( ii > 0 && fff > 0.0 && fff <= 1.0 ) minfrac = fff ;
01815       else                                    minfrac = DEFAULT_MINFRAC ;
01816    }
01817 
01818    eee = my_getenv("AFNI_IMAGE_MAXFRAC") ;
01819    if( eee != NULL ){
01820       float fff=0.0 ; int ii ;
01821       ii = sscanf(eee,"%f",&fff) ;
01822       if( ii > 0 && fff > 0.0 && fff <= 1.0 ) maxfrac = fff ;
01823       else                                    maxfrac = DEFAULT_MAXFRAC ;
01824    }
01825 
01826    dc = seq->dc ;
01827 
01828    { float xxx = xwide , yyy = yhigh ;
01829      float fff = (xxx*yyy)/(dc->width*dc->height) , ggg ;
01830 
01831      
01832 
01833      if( fff < minfrac ){
01834        fff = sqrt(minfrac/fff) ; xxx *= fff ; yyy *= fff ; 
01835      }
01836 
01837      
01838 
01839      fff = ggg = 1.0 ;
01840      if( xxx >= maxfrac*dc->width ) fff = maxfrac*dc->width / xxx ; 
01841      if( yyy >= maxfrac*dc->height) ggg = maxfrac*dc->height/ yyy ; 
01842      fff = MIN(fff,ggg) ; xxx *= fff ; yyy *= fff ;
01843      if( xxx < 1.0 || yyy < 1.0 ){                      
01844         xxx = xwide ; yyy = yhigh ;                    
01845      }
01846 
01847      xwide = (int)( 0.49 + xxx ) ;
01848      yhigh = (int)( 0.49 + yyy ) ;
01849    }
01850 
01851 if( PRINT_TRACING ){
01852   char str[256] ;
01853   sprintf(str,"last wid=%f hei=%f  new wid=%f hei=%f",
01854           seq->last_width_mm,seq->last_height_mm,new_width_mm,new_height_mm ) ;
01855   STATUS(str) ;
01856   sprintf(str,"new xwide=%d yhigh=%d  scale_x=%f _y=%f",
01857           xwide,yhigh,scale_x,scale_y) ;
01858   STATUS(str) ;
01859 }
01860 
01861    seq->last_width_mm  = new_width_mm ;
01862    seq->last_height_mm = new_height_mm ;
01863 
01864    
01865 
01866    if( seq->onoff_state ){
01867      float fff,ggg ;
01868      xwide = (int) ( 0.49 + xwide / seq->image_frac ) ;  
01869      yhigh = (int) ( 0.49 + yhigh / seq->image_frac ) ;
01870 
01871      fff = ggg = 1.0 ;
01872      if( xwide >= maxfrac*dc->width ) fff = maxfrac*dc->width /xwide; 
01873      if( yhigh >= maxfrac*dc->height) ggg = maxfrac*dc->height/yhigh; 
01874      fff = MIN(fff,ggg) ;
01875      fff = MIN(fff,ggg) ; xwide *= fff ; yhigh *= fff ;
01876    }
01877 
01878    if( seq->opt.free_aspect ){
01879       XtVaSetValues( seq->wtop ,
01880                        XmNminAspectX ,  1 ,   
01881                        XmNminAspectY , 20 ,
01882                        XmNmaxAspectX , 20 ,
01883                        XmNmaxAspectY ,  1 ,
01884                      NULL ) ;
01885    } else {
01886       XtVaSetValues( seq->wtop ,
01887                        XmNminAspectX , xwide ,   
01888                        XmNminAspectY , yhigh ,
01889                        XmNmaxAspectX , xwide ,
01890                        XmNmaxAspectY , yhigh ,
01891                      NULL ) ;
01892    }
01893 
01894    XtVaSetValues( seq->wtop ,
01895                      XmNwidth  , xwide ,      
01896                      XmNheight , yhigh ,
01897                   NULL ) ;
01898 
01899    
01900 
01901    MCW_widget_geom( seq->wtop , &wx,&hy,&xx,&yy ) ;
01902 
01903    if( xx+wx/2 < 1 ) xp = 10 ; else xp = xx ;
01904    if( yy+hy/2 < 1 ) yp = 10 ; else yp = yy ;
01905 
01906    if( xp != xx || yp != yy )
01907       XtVaSetValues( seq->wtop , XmNx , xp , XmNy , yp , NULL ) ;
01908 
01909    
01910 
01911    if( seq->dialog != NULL && XtIsRealized( seq->dialog ) )
01912       ISQ_place_dialog( seq ) ;
01913 
01914    EXRETURN ;
01915 }
01916 
01917 
01918 
01919 
01920 
01921 MCW_imseq_status * ISQ_copy_status( MCW_imseq_status * instat )
01922 {
01923    MCW_imseq_status * outstat ;
01924 
01925 ENTRY("ISQ_copy_status") ;
01926 
01927    outstat = (MCW_imseq_status *) XtMalloc( sizeof(MCW_imseq_status) ) ;
01928 
01929    *outstat = *instat ;   
01930    RETURN(outstat) ;
01931 }
01932 
01933 
01934 
01935 char * ISQ_opacity_label( int val ) 
01936 {
01937    static char dig[] = "0123456789" , buf[3] ;
01938 
01939    buf[0] = dig[val] ; buf[1] = '\0' ; return buf ;
01940 }
01941 
01942 
01943 
01944 void ISQ_opacity_CB( MCW_arrowval * av , XtPointer cd ) 
01945 {
01946    MCW_imseq * seq = (MCW_imseq *) cd ;
01947    char * buf = ISQ_opacity_label(av->ival) ;
01948    XmString xstr = XmStringCreateLtoR( buf , XmFONTLIST_DEFAULT_TAG ) ;
01949 
01950    XtVaSetValues( av->wlabel , XmNlabelString , xstr , NULL ) ;
01951    XmStringFree( xstr ) ;
01952 
01953    seq->ov_opacity = OPACITY_FAC * av->ival ;
01954    ISQ_redisplay( seq , -1 , isqDR_display ) ;
01955    return ;
01956 }
01957 
01958 
01959 
01960 
01961 
01962 void ISQ_zoom_av_CB( MCW_arrowval *apv , XtPointer cd ) 
01963 {
01964    MCW_imseq    *seq = (MCW_imseq *) cd ;
01965    MCW_arrowval *av  = seq->zoom_val_av ;
01966    XmString xstr ;
01967    int zlev=av->ival , zold=seq->zoom_fac ;
01968 
01969 ENTRY("ISQ_zoom_av_CB") ;
01970 
01971    if( !ISQ_REALZ(seq) || av != apv ) EXRETURN ;  
01972 
01973    if( seq->mont_nx > 1 || seq->mont_ny > 1 ){   
01974 #if 0
01975 fprintf(stderr,"zoom: montage nx=%d ny=%d\n",seq->mont_nx,seq->mont_ny) ;
01976 #endif
01977      AV_assign_ival(av,ZOOM_BOT) ; seq->zoom_fac = 1 ;
01978      XBell(seq->dc->display,100); EXRETURN;
01979    }
01980    if( seq->dialog != NULL && seq->dialog_starter == NBUT_MONT ){
01981 #if 0
01982 fprintf(stderr,"zoom: dialog_starter = %d\n",seq->dialog_starter) ;
01983 #endif
01984      AV_assign_ival(av,ZOOM_BOT) ; seq->zoom_fac = 1 ;
01985      XBell(seq->dc->display,100); EXRETURN;
01986    }
01987 
01988    
01989 
01990    xstr = XmStringCreateLtoR( (zlev==1)?"z":"Z" , XmFONTLIST_DEFAULT_TAG );
01991    XtVaSetValues( av->wlabel , XmNlabelString , xstr , NULL ) ;
01992    XmStringFree( xstr ) ;
01993 
01994    seq->zoom_fac = zlev ;   
01995    if( zlev == 1 ){
01996       seq->zoom_hor_off = seq->zoom_ver_off = 0.0 ; 
01997    } else {
01998       float mh = (zlev-1.001)/zlev ;        
01999       float dh = 0.5*(1.0/zold-1.0/zlev) ;  
02000                                             
02001       seq->zoom_hor_off += dh ;
02002       seq->zoom_ver_off += dh ;
02003            if( seq->zoom_hor_off > mh  ) seq->zoom_hor_off = mh  ;
02004       else if( seq->zoom_hor_off < 0.0 ) seq->zoom_hor_off = 0.0 ;
02005            if( seq->zoom_ver_off > mh  ) seq->zoom_ver_off = mh  ;
02006       else if( seq->zoom_ver_off < 0.0 ) seq->zoom_ver_off = 0.0 ;
02007    }
02008 
02009    
02010 
02011    SENSITIZE( seq->zoom_drag_pb , (zlev>1) ) ;
02012 
02013    AV_SENSITIZE_DOWN( av , (zlev > 1       ) ) ;
02014    AV_SENSITIZE_UP  ( av , (zlev < ZOOM_TOP) ) ;
02015 
02016    if( zlev == 1 && seq->zoom_button1 ){       
02017       seq->zoom_button1 = 0 ;
02018       MCW_invert_widget( seq->zoom_drag_pb ) ;
02019       POPUP_cursorize( seq->wimage ) ;
02020    }
02021 
02022    
02023 
02024    if( seq->zoom_pixmap != (Pixmap) 0 ){
02025       XFreePixmap( seq->dc->display , seq->zoom_pixmap ) ;
02026       seq->zoom_pixmap = (Pixmap) 0 ; seq->zoom_pw = seq->zoom_ph = 0 ;
02027    }
02028 
02029    
02030 
02031    MCW_kill_XImage(seq->zoom_xim) ; seq->zoom_xim = NULL ;
02032 
02033    
02034 
02035    ISQ_redisplay( seq , -1 , isqDR_display ) ;
02036 
02037    EXRETURN ;
02038 }
02039 
02040 
02041 
02042 
02043 void ISQ_zoom_pb_CB( Widget w , XtPointer client_data , XtPointer call_data )
02044 {
02045    MCW_imseq * seq = (MCW_imseq *) client_data ;
02046 
02047 ENTRY("ISQ_zoom_pb_CB") ;
02048 
02049    if( ! ISQ_REALZ(seq)       ||
02050        w != seq->zoom_drag_pb ||
02051        seq->zoom_fac == 1       ) EXRETURN ; 
02052 
02053    if( seq->cursor_state != CURSOR_NORMAL ){ 
02054      XBell(XtDisplay(w),100); EXRETURN;
02055    }
02056 
02057    seq->zoom_button1 = !seq->zoom_button1 ; 
02058 
02059    if( seq->zoom_button1 ) HAND_cursorize ( seq->wimage ) ;
02060    else                    POPUP_cursorize( seq->wimage ) ;
02061 
02062    MCW_invert_widget( seq->zoom_drag_pb ) ;
02063 
02064    if( seq->crop_drag ){                       
02065      MCW_invert_widget( seq->crop_drag_pb ) ;  
02066      seq->crop_drag = 0 ;
02067    }
02068 
02069    EXRETURN ;
02070 }
02071 
02072 
02073 
02074 
02075 
02076 void ISQ_actually_pan( MCW_imseq *seq , int lr , int ud )  
02077 {
02078    float hh,vv , mh,dh , hhold,vvold ;
02079 
02080 ENTRY("ISQ_actually_pan") ;
02081 
02082    if( !ISQ_REALZ(seq) || seq->zoom_fac == 1 || seq->zoom_xim == NULL ) EXRETURN;
02083 
02084    mh = (seq->zoom_fac-1.001)/seq->zoom_fac ;  
02085    dh = 0.020/seq->zoom_fac ;                  
02086    hh=seq->zoom_hor_off ; hhold=hh ;           
02087    vv=seq->zoom_ver_off ; vvold=vv ;
02088 
02089    hh += lr*dh ;
02090         if( hh < 0.0) hh = 0.0 ;
02091    else if( hh > mh ) hh = mh  ;
02092 
02093    vv += ud*dh ;
02094         if( vv < 0.0) vv = 0.0 ;
02095    else if( vv > mh ) vv = mh  ;
02096 
02097    if( vv == vvold && hh == hhold ) EXRETURN ; 
02098 
02099    seq->zoom_hor_off = hh ;                    
02100    seq->zoom_ver_off = vv ;
02101    ISQ_show_zoom( seq ) ;                      
02102    EXRETURN ;
02103 }
02104 
02105 
02106 
02107 
02108 void ISQ_crop_pb_CB( Widget w , XtPointer client_data , XtPointer call_data )
02109 {
02110    MCW_imseq * seq = (MCW_imseq *) client_data ;
02111 
02112 ENTRY("ISQ_crop_pb_CB") ;
02113 
02114    if( !ISQ_REALZ(seq)        ||
02115        w != seq->crop_drag_pb ||
02116        ! seq->crop_allowed      ){ XBell(XtDisplay(w),100); EXRETURN; }
02117 
02118    MCW_invert_widget( seq->crop_drag_pb ) ;
02119    seq->crop_drag = !seq->crop_drag ;
02120 
02121    if( !seq->crop_drag && seq->cropit ){        
02122      seq->cropit = 0 ; seq->crop_nxorg = -1 ;   
02123      ISQ_redisplay( seq , -1 , isqDR_display ) ;
02124    }
02125 
02126    if( seq->zoom_button1 ){                     
02127      POPUP_cursorize( seq->wimage ) ;
02128      MCW_invert_widget( seq->zoom_drag_pb ) ;
02129      seq->zoom_button1 = 0 ;
02130    }
02131 
02132    EXRETURN ;
02133 }
02134 
02135 
02136 
02137 MRI_IMAGE * ISQ_index_to_rgb( MCW_DC *dc , int overlay , MRI_IMAGE *im ) 
02138 {
02139    register int npix,ii,jj ;
02140    MRI_IMAGE *outim ;
02141    register byte *our ;
02142    register short *iar ;
02143 
02144 ENTRY("ISQ_short_to_rgb") ;
02145 
02146    if( dc == NULL || im == NULL || im->kind != MRI_short ) RETURN(NULL) ;
02147 
02148    npix  = im->nvox ;
02149    iar   = MRI_SHORT_PTR(im) ;
02150    outim = mri_new_conforming( im , MRI_rgb ) ;
02151    our   = MRI_RGB_PTR(outim) ;
02152 
02153    if( !overlay ){
02154       for( jj=ii=0 ; ii < npix ; ii++,jj+=3 ){
02155          if( iar[ii] >= 0 ){                         
02156             our[jj  ] = DC_REDBYTE  (dc,iar[ii]) ;
02157             our[jj+1] = DC_GREENBYTE(dc,iar[ii]) ;
02158             our[jj+2] = DC_BLUEBYTE (dc,iar[ii]) ;
02159          } else {                                    
02160             our[jj  ] = DCOV_REDBYTE  (dc,-iar[ii]) ;
02161             our[jj+1] = DCOV_GREENBYTE(dc,-iar[ii]) ;
02162             our[jj+2] = DCOV_BLUEBYTE (dc,-iar[ii]) ;
02163          }
02164       }
02165    } else {                                      
02166       for( jj=ii=0 ; ii < npix ; ii++,jj+=3 ){
02167          if( iar[ii] > 0 ){                         
02168             our[jj  ] = DCOV_REDBYTE(dc,iar[ii]) ;
02169             our[jj+1] = DCOV_GREENBYTE(dc,iar[ii]) ;
02170             our[jj+2] = DCOV_BLUEBYTE(dc,iar[ii]) ;
02171          } else {                                   
02172             our[jj] = our[jj+1] = our[jj+2] = 0 ;
02173          }
02174       }
02175    }
02176 
02177    RETURN(outim) ;
02178 }
02179 
02180 
02181 
02182 
02183 
02184 
02185 
02186 
02187 
02188 
02189 
02190 
02191 
02192 
02193 MRI_IMAGE * ISQ_overlay( MCW_DC *dc, MRI_IMAGE *ulim, MRI_IMAGE *ovim, float alpha )
02194 {
02195    register int npix,ii,jj ;
02196    MRI_IMAGE *outim , *orim ;
02197    register byte *orr, *our ;
02198 
02199 ENTRY("ISQ_overlay") ;
02200 
02201    if( dc == NULL || ulim == NULL || ovim == NULL || alpha <= 0.0 ) RETURN(NULL) ;
02202 
02203    npix = ulim->nvox ;
02204 
02205    if( ovim->nvox != npix ) RETURN(NULL) ;
02206 
02207    
02208 
02209    if( ulim->kind == MRI_short && ovim->kind == MRI_short && alpha > 0.99 ){
02210       register short *tar , *oar=MRI_SHORT_PTR(ovim) , *iar=MRI_SHORT_PTR(ulim) ;
02211 
02212       outim = mri_new_conforming( ulim , MRI_short ) ;
02213       tar = MRI_SHORT_PTR( outim ) ;
02214       for( ii=0 ; ii < npix ; ii++ )
02215          tar[ii] = (oar[ii] <= 0) ? iar[ii] : -oar[ii] ;
02216 
02217       RETURN(outim) ;
02218    }
02219 
02220    
02221 
02222    switch( ulim->kind ){              
02223       case MRI_rgb:                   
02224          outim = mri_copy(ulim) ;
02225          our   = MRI_RGB_PTR(outim) ;
02226       break ;
02227 
02228       default:
02229          RETURN(NULL) ; break ;   
02230 
02231       case MRI_short:
02232          outim = ISQ_index_to_rgb( dc , 0 , ulim ) ;
02233          our   = MRI_RGB_PTR(outim) ;
02234       break ;
02235    }
02236 
02237    switch( ovim->kind ){    
02238       case MRI_rgb:
02239          orim = ovim ; orr = MRI_RGB_PTR(orim) ; break ;
02240 
02241       default:
02242          mri_free(outim) ;
02243          RETURN(NULL) ; break ;              
02244 
02245       case MRI_short:
02246          orim = ISQ_index_to_rgb( dc , 1 , ovim ) ;
02247          orr  = MRI_RGB_PTR(orim) ;
02248       break ;
02249    }
02250 
02251    
02252 
02253    if( alpha > 0.99 ){                          
02254       for( jj=ii=0 ; ii < npix ; ii++,jj+=3 ){
02255          if( orr[jj] > 0 || orr[jj+1] > 0 || orr[jj+2] > 0 ){
02256             our[jj  ] = orr[jj  ] ;
02257             our[jj+1] = orr[jj+1] ;
02258             our[jj+2] = orr[jj+2] ;
02259          }
02260       }
02261    } else {                                     
02262       register float aa=alpha , bb=1.0-alpha ;
02263       for( jj=ii=0 ; ii < npix ; ii++,jj+=3 ){
02264          if( orr[jj] > 0 || orr[jj+1] > 0 || orr[jj+2] > 0 ){
02265             our[jj  ] = aa*orr[jj  ] + bb*our[jj  ] ;  
02266             our[jj+1] = aa*orr[jj+1] + bb*our[jj+1] ;
02267             our[jj+2] = aa*orr[jj+2] + bb*our[jj+2] ;
02268          }
02269       }
02270    }
02271 
02272    if( orim != ovim ) mri_free(orim) ;  
02273 
02274    RETURN(outim) ;
02275 }
02276 
02277 
02278 
02279 
02280 
02281 void ISQ_make_bar( MCW_imseq * seq )
02282 {
02283    MRI_IMAGE * im ;
02284    int iy , ny ;
02285    short * ar ;
02286 
02287 ENTRY("ISQ_make_bar") ;
02288 
02289    if( ! ISQ_VALID(seq) ) EXRETURN ;
02290 
02291    KILL_2XIM( seq->given_xbar , seq->sized_xbar ) ;
02292 
02293    ny = seq->dc->ncol_im ;
02294    im = mri_new( 1 , ny , MRI_short ) ;
02295    ar = mri_data_pointer( im ) ;
02296 
02297    for( iy=0 ; iy < ny ; iy++ ) ar[iy] = ny-1-iy ;
02298 
02299    seq->given_xbar = mri_to_XImage( seq->dc , im ) ;
02300 
02301    KILL_1MRI( im ) ;
02302    EXRETURN ;
02303 }
02304 
02305 
02306 
02307 
02308 
02309 
02310 
02311 
02312 
02313 void ISQ_make_image( MCW_imseq *seq )
02314 {
02315    MRI_IMAGE *im , *ovim , *tim ;
02316    Boolean reset_done = False ;
02317 
02318 ENTRY("ISQ_make_image") ;
02319 
02320    if( ! ISQ_VALID(seq) ) EXRETURN ;
02321 
02322    
02323 
02324    if( seq->mont_nx > 1 || seq->mont_ny > 1 ){
02325      ISQ_make_montage( seq ) ;
02326      EXRETURN ;
02327    }
02328 
02329    KILL_2XIM( seq->given_xim , seq->sized_xim ) ;  
02330 
02331    if( seq->mplot != NULL ){                            
02332      delete_memplot( seq->mplot ) ; seq->mplot = NULL ;
02333    }
02334 
02335    
02336 
02337    if( seq->opt.rot         != seq->old_opt.rot         ||
02338        seq->opt.mirror      != seq->old_opt.mirror      ||
02339        seq->opt.scale_group != seq->old_opt.scale_group ||
02340        seq->opt.scale_range != seq->old_opt.scale_range ||
02341        seq->mont_nx         != seq->mont_nx_old         ||
02342        seq->mont_ny         != seq->mont_ny_old           ){
02343 
02344       KILL_1MRI( seq->imim ) ;  
02345       KILL_1MRI( seq->ovim ) ;
02346    }
02347 
02348    
02349 
02350    im = seq->imim ;
02351 
02352    if( im == NULL ){
02353       float new_width_mm , new_height_mm ;
02354 
02355       tim = ISQ_getimage( seq->im_nr , seq ) ;
02356 
02357       if( tim == NULL ){
02358 #if 0
02359          fprintf(stderr,
02360                  "\n*** error in ISQ_make_image: NULL image returned for display! ***\n") ;
02361 #endif
02362          EXRETURN ;
02363       }
02364 
02365       seq->last_image_type = tim->kind ;
02366 
02367       seq->set_orim = (seq->need_orim != 0) ;  
02368       seq->imim = im = ISQ_process_mri( seq->im_nr , seq , tim ) ;
02369       KILL_1MRI(tim) ;
02370       seq->set_orim = 0 ;
02371 
02372       seq->barbot = seq->clbot ; 
02373       seq->bartop = seq->cltop ;
02374       ISQ_set_barhint(seq,NULL) ;
02375 
02376       
02377 
02378       new_width_mm  = IM_WIDTH(im) ;
02379       new_height_mm = IM_HEIGHT(im) ;
02380 
02381       seq->horig = im->nx ;  seq->last_dx = fabs(im->dx) ;
02382       seq->vorig = im->ny ;  seq->last_dy = fabs(im->dy) ;
02383 
02384       if( FLDIF(new_width_mm ,seq->last_width_mm ) ||
02385           FLDIF(new_height_mm,seq->last_height_mm)   ){
02386 
02387          if( PRINT_TRACING ){
02388            char str[256] ;
02389            sprintf(str,"nx=%d ny=%d dx=%f dy=%f wid=%f hei=%f",
02390                   im->nx,im->ny,im->dx,im->dy,new_width_mm,new_height_mm) ;
02391            STATUS(str) ;
02392          }
02393 
02394          ISQ_reset_dimen( seq , new_width_mm , new_height_mm ) ;
02395          reset_done = True ;
02396       }
02397    }
02398 
02399    if( seq->opt.free_aspect != seq->old_opt.free_aspect && !reset_done )
02400       ISQ_reset_dimen( seq , seq->last_width_mm , seq->last_height_mm ) ;
02401 
02402    
02403 
02404    if( ISQ_SKIP_OVERLAY(seq) ){
02405      KILL_1MRI( seq->ovim ) ;
02406      ovim = NULL ;
02407    } else {
02408      char *lab ;        
02409 
02410      ovim = seq->ovim ;
02411      if( ovim == NULL ){
02412         tim = ISQ_getoverlay( seq->im_nr , seq ) ;
02413 
02414         if( tim != NULL && !ISQ_GOOD_OVERLAY_TYPE(tim->kind) ){
02415           fprintf(stderr,"\a\n*** Illegal overlay image kind=%d! ***\n",tim->kind) ;
02416           KILL_1MRI(tim) ;
02417         }
02418 
02419         if( tim != NULL )
02420           ovim = seq->ovim =
02421             mri_flippo( ISQ_TO_MRI_ROT(seq->opt.rot) , seq->opt.mirror , tim ) ;
02422 
02423         if( tim != ovim ) KILL_1MRI(tim) ;
02424      }
02425 
02426      
02427 
02428      if( MCW_val_bbox(seq->wbar_plots_bbox) != 0 ){
02429        seq->mplot = ISQ_getmemplot( seq->im_nr , seq ) ;
02430        if( seq->mplot != NULL )
02431          flip_memplot( ISQ_TO_MRI_ROT(seq->opt.rot),seq->opt.mirror, seq->mplot );
02432      }
02433 
02434      
02435 
02436      if( seq->wbar_label_av->ival != 0 ){
02437        lab = ISQ_getlabel( seq->im_nr , seq ) ;
02438        if( lab != NULL ){
02439          MEM_plotdata *mp = ISQ_plot_label( seq , lab ) ;
02440          if( mp != NULL ){
02441            if( seq->mplot != NULL ){
02442              append_to_memplot( seq->mplot , mp ) ; delete_memplot( mp ) ;
02443            } else {
02444              seq->mplot = mp ;
02445            }
02446          }
02447          free(lab) ;
02448        }
02449      }
02450 
02451    } 
02452 
02453    
02454 
02455    seq->old_opt = seq->opt ;
02456 
02457    seq->mont_nx_old = seq->mont_ny_old = 1 ;
02458 
02459    STATUS("making given_xim");
02460 
02461    
02462 
02463    if( ovim == NULL || ISQ_SKIP_OVERLAY(seq) ){          
02464 
02465       tim = im ;
02466 #if 1
02467    } else {                                                
02468 
02469       tim = ISQ_overlay( seq->dc, im, ovim, seq->ov_opacity ) ;
02470       if( tim == NULL ) tim = im ;                    
02471 
02472 #else
02473    } else if( im->kind == MRI_short ){                    
02474       register short * tar , * oar , * iar ;
02475       register int ii , npix = im->nx * im->ny ;
02476 
02477       STATUS("overlaying onto 'im'") ;
02478 
02479       tim = mri_new( im->nx , im->ny , MRI_short ) ;
02480       tar = MRI_SHORT_PTR( tim ) ;                      
02481       oar = MRI_SHORT_PTR( ovim ) ;                     
02482       iar = MRI_SHORT_PTR( im ) ;                       
02483       for( ii=0 ; ii < npix ; ii++ )
02484          tar[ii] = (oar[ii] == 0) ? iar[ii] : -oar[ii] ;
02485 
02486    } else if( im->kind == MRI_rgb ){                       
02487       register int ii , npix = im->nx * im->ny ;
02488       register short *oar = MRI_SHORT_PTR(ovim) ;
02489       register byte *tar , *iar = MRI_RGB_PTR(im) ;
02490       register Pixel *negpix = seq->dc->ovc->pix_ov ;
02491 
02492       tim = mri_to_rgb( im ) ; tar = MRI_RGB_PTR(tim) ;
02493 
02494       for( ii=0 ; ii < npix ; ii++ )
02495         if( oar[ii] > 0 )
02496           DC_pixel_to_rgb( seq->dc, negpix[oar[ii]],
02497                            tar+(3*ii),tar+(3*ii+1),tar+(3*ii+2) ) ;
02498 #endif
02499    }
02500 
02501    
02502 
02503    STATUS("converting to XImage") ;
02504    seq->given_xim = mri_to_XImage( seq->dc , tim ) ;
02505 
02506    if( tim != im ) KILL_1MRI(tim) ;
02507 
02508    EXRETURN ;
02509 }
02510 
02511 
02512 
02513 
02514 
02515 MEM_plotdata * ISQ_plot_label( MCW_imseq *seq , char *lab )
02516 {
02517    MEM_plotdata *mp ; int ww ; float asp , dd ;
02518    static int sz[5] = { 20 , 28 , 40 , 56 , 80 } ;  
02519    char *eee ; float rr=1.0,gg=1.0,bb=0.8 , sb=0.003 ;
02520 
02521 ENTRY("ISQ_plot_label") ;
02522 
02523    if( !ISQ_REALZ(seq) || lab  == NULL ) RETURN(NULL) ;
02524 
02525    asp = 1.0 ;
02526 
02527    
02528 
02529    ww = sz[seq->wbar_labsz_av->ival] ;
02530    if( asp > 1.0 ) ww = (int)(ww/asp+0.5) ;
02531 
02532    dd = 0.0007*ww ;  
02533 
02534    create_memplot_surely( "Ilabelplot" , asp ) ;
02535    set_thick_memplot(0.0) ;
02536 
02537    
02538 
02539    eee = getenv("AFNI_IMAGE_LABEL_COLOR") ;
02540    if( eee != NULL )
02541       DC_parse_color( seq->dc , eee , &rr,&gg,&bb ) ;
02542    set_color_memplot(rr,gg,bb) ;
02543 
02544    
02545 
02546    eee = getenv("AFNI_IMAGE_LABEL_SETBACK") ;
02547    if( eee != NULL ){
02548       float ss = strtod(eee,NULL) ;
02549       if( ss >= 0.0 && ss < 0.5 ) sb = ss ;
02550    }
02551 
02552    
02553 
02554    switch( seq->wbar_label_av->ival ){
02555       default:
02556       case ISQ_LABEL_UPLF:
02557          plotpak_pwritf( sb,1.0-dd-sb , lab , ww , 0 , -1 ) ; break ;
02558 
02559       case ISQ_LABEL_UPRT:
02560          plotpak_pwritf( asp-sb,1.0-dd-sb , lab , ww , 0 ,  1 ) ; break ;
02561 
02562       case ISQ_LABEL_DNLF:
02563          plotpak_pwritf( sb,dd+sb , lab , ww , 0 , -1 ) ; break ;
02564 
02565       case ISQ_LABEL_DNRT:
02566          plotpak_pwritf( asp-sb,dd+sb , lab , ww , 0 ,  1 ) ; break ;
02567 
02568       case ISQ_LABEL_UPMD:
02569          plotpak_pwritf( 0.5*asp,1.0-dd-sb , lab , ww , 0 , 0 ) ; break ;
02570 
02571       case ISQ_LABEL_DNMD:
02572          plotpak_pwritf( 0.5*asp,dd+sb , lab , ww , 0 , 0 ) ; break ;
02573    }
02574 
02575    mp = get_active_memplot() ; RETURN(mp) ;
02576 }
02577 
02578 
02579 
02580 
02581 
02582 
02583 MRI_IMAGE * ISQ_process_mri( int nn , MCW_imseq *seq , MRI_IMAGE *im )
02584 {
02585    MRI_IMAGE *newim , *flipim , *lim ;
02586    int  scl_grp ;
02587    short clbot=0 , cltop=0 ;
02588    int must_rescale = 1 ;     
02589    int have_transform ;
02590 
02591 ENTRY("ISQ_process_mri") ;
02592 
02593    seq->clbot = seq->cltop = 0.0 ; 
02594 
02595    if( ! ISQ_VALID(seq) || im == NULL ) RETURN(NULL) ;
02596 
02597    
02598 
02599    lim = im ;  
02600 
02601    if( im->kind == MRI_complex ){
02602       float *lar ; complex *cxar ; int ii , npix ;
02603 
02604       DPRI("complex to real code = ",seq->opt.cx_code) ;
02605 
02606       lim  = mri_new( im->nx , im->ny , MRI_float ) ;
02607       lar  = MRI_FLOAT_PTR(lim) ;
02608       cxar = MRI_COMPLEX_PTR(im) ;
02609       npix = im->nx * im->ny ;
02610       MRI_COPY_AUX(lim,im) ;
02611       must_rescale = 1 ;  
02612 
02613       switch( seq->opt.cx_code ){
02614 
02615          default:
02616          case ISQ_CX_MAG:
02617             for( ii=0 ; ii < npix ; ii++ ) lar[ii] = CABS(cxar[ii]) ;
02618          break ;
02619 
02620          case ISQ_CX_PHASE:
02621             for( ii=0 ; ii < npix ; ii++ ) lar[ii] = CARG(cxar[ii]) ;
02622          break ;
02623 
02624          case ISQ_CX_REAL:
02625             for( ii=0 ; ii < npix ; ii++ ) lar[ii] = cxar[ii].r ;
02626          break ;
02627 
02628          case ISQ_CX_IMAG:
02629             for( ii=0 ; ii < npix ; ii++ ) lar[ii] = cxar[ii].i ;
02630          break ;
02631       }
02632    }
02633 
02634    have_transform = (seq->transform0D_func != NULL ||
02635                      seq->transform2D_func != NULL   ) ;
02636 
02637    
02638 
02639    if( lim->kind == MRI_rgb ){
02640       MRI_IMAGE *tim , *qim ;
02641 
02642 
02643 
02644       if( have_transform ) qim = mri_copy( lim ) ;
02645       else                 qim = lim ;
02646 
02647       if( seq->transform0D_func != NULL )
02648         mri_rgb_transform_nD( qim, 0, seq->transform0D_func ) ;
02649 
02650       if( seq->transform2D_func != NULL )
02651         mri_rgb_transform_nD( qim, 2, seq->transform2D_func ) ;
02652 
02653 
02654 
02655       if( (seq->opt.improc_code & ISQ_IMPROC_FLAT) != 0 ){
02656         tim = mri_flatten_rgb( qim ) ;
02657         if( qim != lim ) mri_free(qim) ;
02658         qim = tim ;
02659       }
02660 
02661 
02662 
02663       if( (seq->opt.improc_code & ISQ_IMPROC_SHARP) != 0 ){
02664         tim = mri_sharpen_rgb( seq->sharp_fac , qim ) ;
02665         if( qim != lim ) mri_free(qim) ;
02666         qim = tim ;
02667       }
02668 
02669 
02670 
02671 
02672 
02673       if( qim == lim )
02674         newim = mri_copy( lim ) ;   
02675       else
02676         newim = qim ;               
02677 
02678 
02679 
02680       if( fabs(1.0-seq->rgb_gamma)  > 0.02 || fabs(seq->rgb_offset) > 0.01 ){
02681         register int npix = newim->nx * newim->ny , ii ;
02682         register byte *ar = MRI_RGB_PTR(newim) ;
02683         double gg = seq->rgb_gamma ;
02684         float  aa = seq->rgb_offset , rv,gv,bv , mx ;
02685 
02686         if( aa > 0.9 ) aa = 0.9; else if( aa < -0.9 ) aa = -0.9;
02687         for( ii=0 ; ii < npix ; ii++ ){
02688           if( ar[3*ii] > 0 || ar[3*ii+1] > 0 || ar[3*ii+2] > 0 ){
02689             if( aa != 0.0 ){
02690               rv = ar[3*ii]   ; gv = ar[3*ii+1] ; bv = ar[3*ii+2] ;
02691               mx = MAX(rv,gv) ; mx = (255.0*aa) / MAX(mx,bv) ;
02692               rv *= mx; gv *= mx; bv *= mx;
02693             } else {
02694               rv = gv = bv = 0.0 ;
02695             }
02696             rv += (float)(255.0*pow(ar[3*ii  ]/255.0,gg)) ;
02697             gv += (float)(255.0*pow(ar[3*ii+1]/255.0,gg)) ;
02698             bv += (float)(255.0*pow(ar[3*ii+2]/255.0,gg)) ;
02699             mx = MAX(rv,gv) ; mx = MAX(mx,bv) ;
02700             if( mx > 255.0 ){ mx = 255.0/mx; rv *= mx; gv *= mx; bv *= mx; }
02701             ar[3*ii  ] = BYTEIZE(rv) ;
02702             ar[3*ii+1] = BYTEIZE(gv) ;
02703             ar[3*ii+2] = BYTEIZE(bv) ;
02704           }
02705         }
02706       }
02707 
02708 
02709 
02710       if( seq->set_orim ){                    
02711         KILL_1MRI(seq->orim) ;
02712         seq->orim = mri_to_float(newim) ;    
02713       }
02714 
02715 
02716 
02717       if( seq->zer_color > 0 ){
02718         register int npix = newim->nx * newim->ny , ii ;
02719         register byte rz,gz,bz , *ar = MRI_RGB_PTR(newim) ;
02720         rz = DCOV_REDBYTE  (seq->dc,seq->zer_color) ;  
02721         gz = DCOV_GREENBYTE(seq->dc,seq->zer_color) ;  
02722         bz = DCOV_BLUEBYTE (seq->dc,seq->zer_color) ;  
02723         for( ii=0 ; ii < npix ; ii++ )
02724           if( ar[3*ii] == 0 && ar[3*ii+1] == 0 && ar[3*ii+2] == 0 ){
02725             ar[3*ii] = rz ; ar[3*ii+1] = gz ; ar[3*ii+2] = bz ;
02726           }
02727       }
02728    }  
02729 
02730    
02731    
02732 
02733    else if( ! have_transform && seq->opt.improc_code == ISQ_IMPROC_NONE ){
02734 
02735       if( seq->set_orim ){                   
02736         KILL_1MRI(seq->orim) ;
02737         seq->orim = mri_to_float( lim ) ;
02738       }
02739 
02740       if( !must_rescale && ISQ_DOING_SLICE_PROJ(seq) ) must_rescale = 1 ;
02741 
02742       
02743 
02744       if( nn < seq->status->num_series ){
02745         scl_grp = seq->opt.scale_group ; 
02746       } else {
02747         scl_grp = ISQ_SCL_AUTO ;         
02748       }
02749 
02750       if( seq->rng_bot < seq->rng_top ) scl_grp = ISQ_SCL_USER ;
02751 
02752       switch( scl_grp ){
02753 
02754          case ISQ_SCL_USER:{    
02755            ISQ_SCLEV( seq->rng_bot,seq->rng_top ,
02756                       seq->dc->ncol_im , seq->scl,seq->lev ) ;
02757            clbot = seq->clbot = seq->rng_bot ;
02758            cltop = seq->cltop = seq->rng_top ;
02759          }
02760          break ; 
02761 
02762          default:               
02763          case ISQ_SCL_AUTO:{
02764            ISQ_indiv_statistics *st = &( seq->imstat[nn] ) ;
02765            int scrang = seq->opt.scale_range ;
02766 
02767            if( must_rescale ) st->one_done = False ;
02768 
02769            if( ! st->one_done ) ISQ_statify_one( seq , nn , lim ) ;
02770 
02771            
02772 
02773            if( scrang == ISQ_RNG_02TO98 ){
02774              double ent_th=AFNI_numenv("AFNI_IMAGE_ENTROPY") ;
02775              if( ent_th >= 0.0 ){
02776                if( ent_th == 0.0 ) ent_th = 0.05 ;  
02777                if( st->entropy < ent_th ) scrang = ISQ_RNG_MINTOMAX ;
02778              }
02779            }
02780 
02781            switch( scrang ){
02782 
02783              default:
02784              case ISQ_RNG_MINTOMAX:
02785                seq->scl = st->scl_mm ;
02786                seq->lev = st->lev_mm ;
02787                seq->clbot = st->min ;   
02788                seq->cltop = st->max ;
02789              break ;
02790 
02791              case ISQ_RNG_02TO98:
02792                seq->scl = st->scl_per ;
02793                seq->lev = st->lev_per ;
02794                clbot = seq->clbot = st->per02 ;
02795                cltop = seq->cltop = st->per98 ;
02796              break ;
02797            }
02798          }
02799          break ;  
02800 
02801          case ISQ_SCL_GRP:{         
02802             ISQ_glob_statistics *gl = seq->glstat ;
02803 
02804             switch( seq->opt.scale_range ){
02805 
02806                default:
02807                case ISQ_RNG_MINTOMAX:
02808                  if( ! gl->mm_done ) ISQ_statify_all( seq , True ) ;
02809                  seq->scl = gl->scl_mm ;
02810                  seq->lev = gl->lev_mm ;
02811                  seq->clbot = gl->min ;   
02812                  seq->cltop = gl->max ;
02813                break ;
02814 
02815                case ISQ_RNG_02TO98:
02816                  if( ! gl->per_done ) ISQ_statify_all( seq , False ) ;
02817                  seq->scl = gl->scl_per ;
02818                  seq->lev = gl->lev_per ;
02819                  clbot = seq->clbot = gl->per02 ;
02820                  cltop = seq->cltop = gl->per98 ;
02821                break ;
02822             }
02823          }
02824          break ;  
02825       }  
02826 
02827       
02828 
02829 #if 0
02830       if( lim->kind == MRI_short && clbot < cltop ){
02831 
02832          int npix = lim->nx * lim->ny , ii ;
02833          short *ar = lim->im.short_data ;
02834 
02835          if( seq->rng_ztop == 0 ){
02836             for( ii=0 ; ii < npix ; ii++ )
02837                     if( ar[ii] < clbot ) ar[ii] = clbot ;
02838                else if( ar[ii] > cltop ) ar[ii] = cltop ;
02839          } else {
02840             for( ii=0 ; ii < npix ; ii++ )
02841                     if( ar[ii] < clbot || ar[ii] > cltop ) ar[ii] = clbot ;
02842          }
02843 
02844       } else if( lim->kind == MRI_byte && clbot < cltop ){
02845 
02846          int npix = lim->nx * lim->ny , ii ;
02847          byte *ar = lim->im.byte_data ;
02848 
02849          if( seq->rng_ztop == 0 ){
02850             for( ii=0 ; ii < npix ; ii++ )
02851                     if( ar[ii] < clbot ) ar[ii] = clbot ;
02852                else if( ar[ii] > cltop ) ar[ii] = cltop ;
02853          } else {
02854             for( ii=0 ; ii < npix ; ii++ )
02855                     if( ar[ii] < clbot || ar[ii] > cltop ) ar[ii] = clbot ;
02856          }
02857       }
02858 #endif
02859 
02860       
02861 
02862 DPR("scaling to shorts") ;
02863 
02864                                
02865                                
02866       newim = mri_to_short_sclip( seq->scl, seq->lev, seq->bot, seq->top, lim );
02867 
02868    
02869 
02870    } else {
02871       MRI_IMAGE *tim , *qim ;
02872       double scl , lev ;
02873       float hbot,htop ;
02874 
02875 DPR("begin IMPROCessing") ;
02876 
02877       qim = lim ;  
02878 
02879 
02880 
02881       
02882 
02883       if( seq->transform0D_func != NULL ){
02884          tim = mri_to_float(qim) ;
02885 #if 0
02886          seq->transform0D_func( tim->nvox , MRI_FLOAT_PTR(tim) ) ;
02887 #else
02888          AFNI_CALL_0D_function( seq->transform0D_func ,
02889                                 tim->nvox , MRI_FLOAT_PTR(tim) ) ;
02890 #endif
02891          if( qim != lim ) mri_free(qim) ;
02892          qim = tim ;
02893       }
02894 
02895       if( seq->transform2D_func != NULL ){
02896          tim = mri_to_float(qim) ;
02897 #if 0
02898          seq->transform2D_func( tim->nx , tim->ny ,
02899                                 tim->dx , tim->dy , MRI_FLOAT_PTR(tim) ) ;
02900 #else
02901          AFNI_CALL_2D_function( seq->transform2D_func ,
02902                                 tim->nx , tim->ny ,
02903                                 tim->dx , tim->dy , MRI_FLOAT_PTR(tim) ) ;
02904 #endif
02905          if( qim != lim ) mri_free(qim) ;
02906          qim = tim ;
02907       }
02908 
02909       
02910 
02911       if( (seq->opt.improc_code & ISQ_IMPROC_FLAT) != 0 ){
02912 DPR("call mri_flatten") ;
02913          tim = mri_flatten( qim ) ;
02914          if( qim != lim ) mri_free(qim) ;
02915          qim = tim ;
02916 
02917          if( seq->opt.scale_range == ISQ_RNG_02TO98 &&
02918              seq->flat_top > seq->flat_bot ){
02919 
02920             float *qar = MRI_FLOAT_PTR(qim) ;
02921             int ii , npix = qim->nx * qim->ny ;
02922 
02923 DPR("clip flattened image") ;
02924 
02925             for( ii=0 ; ii < npix ; ii++ ){
02926                     if( qar[ii] < seq->flat_bot ) qar[ii] = seq->flat_bot ;
02927                else if( qar[ii] > seq->flat_top ) qar[ii] = seq->flat_top ;
02928             }
02929          }
02930       }
02931 
02932       
02933 
02934       if( (seq->opt.improc_code & ISQ_IMPROC_SHARP) != 0 ){
02935 DPR("call mri_sharpen") ;
02936          tim = mri_sharpen( seq->sharp_fac , 0 , qim ) ;
02937          if( qim != lim ) mri_free(qim) ;
02938          qim = tim ;
02939       }
02940 
02941       
02942 
02943       if( (seq->opt.improc_code & ISQ_IMPROC_SOBEL) != 0 ){
02944          int ii , npix ;
02945          float *tar ;
02946 
02947 DPR("call mri_edit_image") ;
02948          tim = mri_edit_image( 0.10 , 1.0 , qim ) ;   
02949          if( qim != lim ) mri_free(qim) ;
02950          qim = tim ;
02951 
02952 DPR("call mri_sobel") ;
02953          tim  = mri_sobel( 0 , 2 , qim ) ;            
02954 
02955 #if 0
02956          npix = tim->nx * tim->ny ;                   
02957          tar  = mri_data_pointer(tim) ;
02958          for( ii=0 ; ii < npix ; ii++ ) tar[ii] = sqrt(tar[ii]) ;
02959 #endif
02960 
02961          if( qim != lim ) mri_free(qim) ;
02962          qim = tim ;
02963       }
02964 
02965       if( seq->set_orim ){                   
02966          KILL_1MRI(seq->orim) ;
02967          seq->orim = mri_to_float( qim ) ;
02968       }
02969 
02970       
02971 
02972       hbot = mri_min(qim) ; htop = mri_max(qim) ;
02973 
02974 DPR("scale to shorts") ;
02975       switch( seq->opt.scale_range ){
02976          default:
02977          case ISQ_RNG_MINTOMAX:
02978             ISQ_SCLEV( hbot,htop , seq->dc->ncol_im , scl,lev ) ;
02979             seq->clbot = hbot ;  
02980             seq->cltop = htop ;
02981          break ;
02982 
02983          case ISQ_RNG_02TO98:{
02984             static int hist[NHISTOG] ;
02985             float h02 , h98 ;
02986 
02987 DPR("call mri_histogram") ;
02988             mri_histogram( qim , hbot,htop , True , NHISTOG,hist ) ;
02989 DPR("call ISQ_perpoints") ;
02990             ISQ_perpoints( hbot,htop , hist , &h02 , &h98 ) ;
02991             ISQ_SCLEV( h02,h98 , seq->dc->ncol_im , scl,lev ) ;
02992             seq->clbot = h02 ;  
02993             seq->cltop = h98 ;
02994          }
02995          break ;
02996       }
02997 
02998       newim = mri_to_short_sclip( scl , lev , seq->bot, seq->top, qim ) ;
02999       if( qim != lim ) mri_free(qim) ;
03000    }
03001 
03002    
03003 
03004 
03005 
03006    if( newim->kind == MRI_short && seq->zer_color > 0 ){
03007      short zz = -seq->zer_color ;
03008      short *ar = MRI_SHORT_PTR(newim) ;
03009      int npix = newim->nx * newim->ny , ii ;
03010 
03011      for( ii=0 ; ii < npix ; ii++ )
03012        if( ar[ii] == seq->bot ) ar[ii] = zz ;
03013    }
03014 
03015 
03016 
03017    MRI_COPY_AUX( newim , lim ) ;
03018 
03019    
03020 
03021 DPR("call mri_flippo") ;
03022    flipim = mri_flippo( ISQ_TO_MRI_ROT(seq->opt.rot) , seq->opt.mirror , newim ) ;
03023 
03024    if( newim != flipim ) KILL_1MRI(newim) ;  
03025    if( lim   != im     ) KILL_1MRI(lim) ;    
03026 
03027    if( seq->set_orim && seq->orim != NULL ){  
03028      MRI_IMAGE *qim ;
03029      qim = mri_flippo( ISQ_TO_MRI_ROT(seq->opt.rot), seq->opt.mirror, seq->orim ) ;
03030      if( qim != seq->orim ){ KILL_1MRI(seq->orim) ; seq->orim = qim ; } ;
03031      MRI_COPY_AUX( seq->orim , flipim ) ;
03032      seq->set_orim = 0 ;
03033    }
03034 
03035    RETURN(flipim) ;
03036 }
03037 
03038 
03039 
03040 
03041 
03042 void ISQ_but_color_CB( Widget w , XtPointer client_data ,
03043                                   XtPointer call_data    )
03044 {
03045    MCW_imseq *seq = (MCW_imseq *) client_data ;
03046 
03047 ENTRY("ISQ_but_color_CB") ;
03048 
03049    if( ! ISQ_REALZ(seq) ) EXRETURN ;
03050 
03051    if( seq->dc->use_xcol_im ) DC_palette_setgray( seq->dc ) ;
03052    else                       DC_palette_setcolor( seq->dc ) ;
03053 
03054    COLORMAP_CHANGE(seq) ;      
03055    ISQ_but_done_reset( seq ) ;
03056    EXRETURN ;
03057 }
03058 
03059 
03060 
03061 void ISQ_but_cswap_CB( Widget w , XtPointer client_data ,
03062                                   XtPointer call_data    )
03063 {
03064    MCW_imseq *seq = (MCW_imseq *) client_data ;
03065 
03066 ENTRY("ISQ_but_cswap_CB") ;
03067 
03068    if( ! ISQ_REALZ(seq) ) EXRETURN ;
03069 
03070    DC_palette_swap( seq->dc ) ;
03071    COLORMAP_CHANGE(seq) ;      
03072    ISQ_but_done_reset( seq ) ;
03073    EXRETURN ;
03074 }
03075 
03076 
03077 
03078 
03079 
03080 void ISQ_saver_CB( Widget w , XtPointer cd , MCW_choose_cbs *cbs )
03081 {
03082    MCW_imseq *seq = (MCW_imseq *) cd ;
03083    int ii , kf ;
03084    MRI_IMAGE *tim , *flim ;
03085    char fname[256] ;
03086    THD_string_array *agif_list=NULL ; 
03087    char tsuf[8] ;                     
03088    float dx,dy ;                      
03089    int dbg ;                          
03090 
03091 #ifndef DONT_USE_METER
03092 #  define METER_MINCOUNT 20
03093    Widget meter = NULL ;
03094    int meter_perc , meter_pold=0 , meter_pbase ;
03095 #endif
03096 
03097 ENTRY("ISQ_saver_CB") ;
03098 
03099    dbg = AFNI_yesenv("AFNI_IMSAVE_DEBUG") ;  
03100 
03101    if( ppmto_agif_filter == NULL && DO_AGIF(seq) ){  
03102       (void) MCW_popup_message( seq->wtop ,
03103                                 "Animated GIF AFNI logic error!\n"
03104                                 "Report to " COXEMAIL , MCW_USER_KILL ) ;
03105       seq->opt.save_agif = 0 ;
03106       EXRETURN ;
03107    }
03108    if( ppmto_mpeg_filter == NULL && DO_MPEG(seq) ){
03109       (void) MCW_popup_message( seq->wtop ,
03110                                 "MPEG-1 AFNI logic error!\n"
03111                                 "Report to " COXEMAIL , MCW_USER_KILL ) ;
03112       seq->opt.save_mpeg = 0 ;
03113       EXRETURN ;
03114    }
03115 
03116    
03117 
03118    if( seq->saver_prefix == NULL ){  
03119       int ll , ii ;
03120 
03121       if( cbs->reason != mcwCR_string ||
03122           cbs->cval == NULL           || (ll = strlen(cbs->cval)) == 0 ){
03123 
03124          XBell( XtDisplay(w) , 100 ) ; EXRETURN ;
03125       }
03126 
03127       seq->saver_prefix = (char*)XtMalloc( sizeof(char) * (ll+8) ) ;
03128       strcpy( seq->saver_prefix , cbs->cval ) ;
03129 
03130       if( seq->saver_prefix[ll-1] != '.' ){  
03131          seq->saver_prefix[ll++] = '.' ;     
03132          seq->saver_prefix[ll]   = '\0' ;
03133       }
03134 
03135       
03136 
03137       if( dbg ) fprintf(stderr,"IMSAVE: got prefix '%s'\n",seq->saver_prefix);
03138 
03139       ll = strlen(seq->saver_prefix) ;
03140 
03141       for( ii=0 ; ii < ll ; ii++ )
03142          if( iscntrl(seq->saver_prefix[ii]) ||
03143              isspace(seq->saver_prefix[ii])   ) break ;
03144 
03145       if( ii < ll || ll < 2 || ll > 240 ){
03146          XBell( XtDisplay(w) , 100 ) ;
03147          myXtFree( seq->saver_prefix ) ; seq->saver_prefix = NULL ;
03148          EXRETURN ;
03149       }
03150 
03151       
03152 
03153       if( seq->opt.save_one && !DO_ANIM(seq) ){
03154          char * ppnm = strstr( seq->saver_prefix , ".pnm." ) ;
03155          int    sll  = strlen( seq->saver_prefix ) ;
03156 
03157          int    mcod = X2M_USE_CMAP ;        
03158          if( seq->opt.save_filter >= 0 ||
03159              seq->mplot != NULL          )   
03160            mcod |= X2M_FORCE_RGB ;           
03161 
03162          
03163 
03164          if( dbg ) fprintf(stderr,"IMSAVE: convert XImage to RGB\n") ;
03165 
03166          reload_DC_colordef( seq->dc ) ;  
03167          tim = XImage_to_mri( seq->dc , seq->given_xim , mcod ) ; 
03168                                                                   
03169 
03170 
03171          if( AFNI_yesenv("AFNI_IMAGE_SAVESQUARE") ){   
03172            tim->dx = seq->last_dx ; tim->dy = seq->last_dy ;
03173            if( dbg ) fprintf(stderr,"  square-ize aspect\n") ;
03174            flim = mri_squareaspect( tim ) ;
03175            if( flim != NULL ){ mri_free(tim); tim = flim; }
03176          }
03177 
03178          
03179 
03180          if( seq->zoom_fac >  1    &&
03181              seq->mont_nx  == 1    &&
03182              seq->mont_ny  == 1    &&
03183              tim           != NULL && tim->kind == MRI_rgb ){
03184 
03185            MRI_IMAGE *qim ;
03186            if( dbg ) fprintf(stderr,"  zooming\n") ;
03187            qim = mri_dup2D(seq->zoom_fac,tim) ;
03188            mri_free(tim) ; tim = qim ;
03189          }
03190 
03191          
03192 
03193          if( tim != NULL && seq->mplot != NULL && tim->kind == MRI_rgb ){
03194            if( dbg ) fprintf(stderr,"  overlay geometry stuff\n") ;
03195            memplot_to_RGB_sef( tim, seq->mplot, 0,0,MEMPLOT_FREE_ASPECT ) ;
03196          }
03197 
03198          
03199 
03200 
03201          if( seq->zoom_fac >  1               &&
03202              seq->mont_nx  == 1               &&
03203              seq->mont_ny  == 1               &&
03204              tim           != NULL            &&
03205              tim->kind     == MRI_rgb         &&
03206              AFNI_yesenv("AFNI_CROP_ZOOMSAVE")  ) {
03207 
03208             MRI_IMAGE *qim ;
03209             int xa,ya , iw=tim->nx/seq->zoom_fac , ih=tim->ny/seq->zoom_fac ;
03210 
03211             if( dbg ) fprintf(stderr,"  crop zoomed image\n") ;
03212             xa = seq->zoom_hor_off * tim->nx ;
03213             if( xa+iw > tim->nx ) xa = tim->nx-iw ;
03214             ya = seq->zoom_ver_off * tim->nx ;
03215             if( ya+ih > tim->ny ) ya = tim->ny-ih ;
03216             qim = mri_cut_2D( tim , xa,xa+iw-1 , ya,ya+ih-1 ) ;
03217             mri_free(tim) ; tim = qim ;
03218          }
03219 
03220          
03221 
03222          if( tim != NULL ){                  
03223             static int warned=0 ;
03224 
03225             if( seq->opt.save_filter < 0 ){  
03226 
03227                if( ppnm == seq->saver_prefix + (sll-5) )  
03228                   seq->saver_prefix[sll-1] = '\0' ;
03229                else
03230                   strcat(seq->saver_prefix,"pnm") ;
03231 
03232                printf("Writing one PNM image to file %s\n",seq->saver_prefix) ;
03233                mri_write_pnm( seq->saver_prefix , tim ) ;
03234 
03235             } else {  
03236 
03237                char filt[512] ; int ff=seq->opt.save_filter ; FILE *fp ;
03238                int pc ;
03239 
03240                
03241 
03242                sprintf( fname, "%s%s", seq->saver_prefix, ppmto_suffix[ff] ) ;
03243                sprintf( filt , ppmto_filter[ff] , fname ) ;
03244                printf("Writing one image to file %s\n",fname) ;
03245                signal( SIGPIPE , SIG_IGN ) ; errno = 0 ;
03246                fp = popen( filt , "w" ) ;
03247                if( fp == NULL ){
03248                   fprintf(stderr,"** Can't open output filter: %s\a\n",filt) ;
03249                   if( errno != 0 ) perror("** Unix error message") ;
03250                   POPDOWN_string_chooser ; mri_free(tim) ; EXRETURN ;
03251                }
03252 
03253                
03254 
03255                fprintf(fp,"P6\n%d %d\n255\n" , tim->nx,tim->ny ) ;
03256                fwrite( MRI_RGB_PTR(tim), sizeof(byte), 3*tim->nvox, fp ) ;
03257                pc = pclose(fp) ;
03258                if( pc == -1 ){
03259                   perror("** Error in image output pipe") ;
03260                   fprintf(stderr,"** filter command was %s\n",filt) ;
03261                   POPDOWN_string_chooser ; mri_free(tim) ; EXRETURN ;
03262                }
03263             }
03264 
03265             mri_free( tim ) ; tim = NULL ;  
03266 
03267             if( seq->dc->visual_class == TrueColor &&
03268                 seq->dc->depth == 16               && !warned ){ 
03269 
03270                warned = 1 ;
03271                fprintf(stderr,
03272                 "\n"
03273                 "*** WARNING: Save One with X11 TrueColor depth=16 can ***\n"
03274                 "***          result in gray pixels not having R=G=B.  ***\n");
03275             }
03276 
03277          } else {
03278             XBell( XtDisplay(w) , 100 ) ;  
03279          }
03280          myXtFree( seq->saver_prefix ) ; seq->saver_prefix = NULL ;
03281          POPDOWN_string_chooser ;
03282          EXRETURN ;
03283       }
03284 
03285       
03286       
03287 
03288       POPDOWN_string_chooser ;
03289 
03290       MCW_choose_integer( w , "Image from" ,
03291                           0 , seq->status->num_total-1 , 0 ,
03292                           ISQ_saver_CB , (XtPointer) seq ) ;
03293 
03294       seq->saver_from = -1 ;
03295       EXRETURN ;
03296    }
03297 
03298    
03299 
03300    if( seq->saver_from == -1 ){  
03301 
03302       if( cbs->reason != mcwCR_integer ){  
03303          XBell( XtDisplay(w) , 100 ) ;
03304          myXtFree( seq->saver_prefix ) ; seq->saver_prefix = NULL ;
03305          EXRETURN ;
03306       }
03307 
03308       if( dbg ) fprintf(stderr,"IMSAVE: got From=%d\n",cbs->ival) ;
03309       seq->saver_from = cbs->ival ;
03310 
03311       POPDOWN_integer_chooser ;
03312 
03313       MCW_choose_integer(
03314           w , "Image to" ,
03315           0 , seq->status->num_total-1 , seq->status->num_total-1 ,
03316           ISQ_saver_CB , (XtPointer) seq ) ;
03317 
03318       seq->saver_to = -1 ;
03319       EXRETURN ;
03320    }
03321 
03322    
03323 
03324    if( cbs->reason != mcwCR_integer ){  
03325       XBell( XtDisplay(w) , 100 ) ;
03326       myXtFree( seq->saver_prefix ) ; seq->saver_prefix = NULL ;
03327       EXRETURN ;
03328    }
03329 
03330    POPDOWN_integer_chooser ;
03331 
03332    if( dbg ) fprintf(stderr,"IMSAVE: got To  =%d\n",cbs->ival) ;
03333 
03334    seq->saver_to = cbs->ival ;
03335 
03336    
03337 
03338    if( seq->saver_prefix == NULL ||
03339        seq->saver_from < 0       ||
03340        seq->saver_to   < 0       ||
03341        seq->saver_from > seq->status->num_total-1 ||
03342        seq->saver_to   > seq->status->num_total-1   ){  
03343 
03344       XBell( XtDisplay(w) , 100 ) ;
03345       myXtFree( seq->saver_prefix ) ; seq->saver_prefix = NULL ;
03346       EXRETURN ;
03347    }
03348 
03349    if( seq->saver_from > seq->saver_to ){  
03350       ii              = seq->saver_from ;
03351       seq->saver_from = seq->saver_to ;
03352       seq->saver_to   = ii ;
03353    }
03354 
03355 #ifndef DONT_USE_METER
03356    meter_pbase = seq->saver_to - seq->saver_from ;
03357    if( meter_pbase >= METER_MINCOUNT ){
03358       meter = MCW_popup_meter( seq->wtop , METER_TOP_WIDE ) ;
03359       meter_pold = 0 ;
03360    } else {
03361       meter = NULL ;
03362    }
03363 #endif
03364 
03365    if( DO_ANIM(seq) ){                     
03366      tsuf[0] = (lrand48()>>5)%26 + 'A' ;   
03367      tsuf[1] = (lrand48()>>5)%26 + 'A' ;   
03368      tsuf[2] = (lrand48()>>5)%26 + 'A' ;   
03369      tsuf[3] = '\0' ;
03370      if( dbg ) fprintf(stderr,"IMSAVE: animation suffix='%s'\n",tsuf) ;
03371    } else {
03372      tsuf[0] = '\0' ;                      
03373    }
03374 
03375 #ifdef USE_GIFF          
03376    if( DO_AGIF(seq) ){
03377      MRI_IMAGE *im = mri_colorsetup( 76 , 6,6,5 ); 
03378      remove( GIFF_MAPFILE ) ;                     
03379      mri_write_pnm( GIFF_MAPFILE , im ) ;
03380      mri_free( im ) ;
03381    }
03382 #endif
03383 
03384    
03385 
03386    for( kf=seq->saver_from ; kf <= seq->saver_to ; kf++ ){
03387 
03388       
03389 
03390       if( dbg ) fprintf(stderr,"IMSAVE: fetch underlay image #%d\n",kf) ;
03391 
03392       tim = ISQ_getimage( kf , seq ) ;
03393 
03394       
03395 
03396       if( tim == NULL ){
03397          if( kf == seq->saver_to && agif_list != NULL ){ 
03398             fprintf(stderr,
03399                     "** Can't save animation: last image in list is NULL!\n");
03400             DESTROY_SARR(agif_list) ;
03401          }
03402          continue ;  
03403       }
03404 
03405       
03406 
03407       flim = tim ;
03408 
03409 #ifndef DONT_USE_METER
03410       if( meter != NULL ){
03411         meter_perc = (int)(100.9 * (kf - seq->saver_from) / meter_pbase) ;
03412         if( meter_perc != meter_pold ){
03413           if( dbg ) fprintf(stderr,"  set meter to %d\n",meter_perc) ;
03414           MCW_set_meter( meter , meter_perc ) ;
03415           meter_pold = meter_perc ;
03416         }
03417       }
03418 #endif
03419 
03420       
03421 
03422       if( seq->opt.save_filter >= 0 || DO_ANIM(seq) ){
03423          char filt[512] ; int ff=seq->opt.save_filter ; FILE *fp ;
03424          MRI_IMAGE * ovim=NULL ;
03425          int nx , ny , npix , pc ;
03426 
03427          
03428 
03429          if( dbg ) fprintf(stderr,"  process image\n") ;
03430 
03431          seq->set_orim = 0 ;
03432          tim  = flim ;
03433          flim = ISQ_process_mri( kf , seq , tim ) ;
03434          if( tim != flim ) KILL_1MRI( tim ) ;
03435 
03436          
03437 
03438          if( !ISQ_SKIP_OVERLAY(seq) ){
03439             if( dbg ) fprintf(stderr,"  fetch overlay image\n") ;
03440             tim = ISQ_getoverlay( kf , seq ) ;
03441             if( tim != NULL && !ISQ_GOOD_OVERLAY_TYPE(tim->kind) ){
03442                KILL_1MRI(tim) ;
03443             }
03444             if( dbg ) fprintf(stderr,"  flip overlay?\n") ;
03445             if( tim != NULL )
03446                ovim = mri_flippo( ISQ_TO_MRI_ROT(seq->opt.rot), seq->opt.mirror, tim );
03447             if( tim != ovim ) KILL_1MRI(tim) ;
03448          }
03449 
03450          
03451 
03452          if( ovim != NULL ){
03453             tim = flim ;
03454             if( dbg ) fprintf(stderr,"  merge overlay and underlay images\n") ;
03455             flim = ISQ_overlay( seq->dc , tim , ovim , seq->ov_opacity ) ;
03456             if( flim == NULL ){ flim = tim ; }     
03457             else              { KILL_1MRI(tim) ; }
03458             mri_free( ovim ) ;
03459          }
03460 
03461          if( AFNI_yesenv("AFNI_IMAGE_SAVESQUARE") ){   
03462            flim->dx = seq->last_dx ; flim->dy = seq->last_dy ;
03463            if( dbg ) fprintf(stderr,"  square-ize aspect ratio\n") ;
03464            tim = mri_squareaspect( flim ) ;
03465            if( tim != NULL ){ mri_free(flim); flim = tim; }
03466          }
03467 
03468          
03469 
03470          if( flim->kind == MRI_short ){
03471             if( dbg ) fprintf(stderr,"  convert to RGB\n") ;
03472             tim = ISQ_index_to_rgb( seq->dc , 0 , flim ) ;
03473             mri_free(flim) ; flim = tim ;
03474          }
03475 
03476          
03477 
03478          if( seq->zoom_fac > 1 && seq->mont_nx == 1 && seq->mont_ny == 1 ){
03479            if( dbg ) fprintf(stderr,"  zoom zoom zoom\n") ;
03480            tim=mri_dup2D(seq->zoom_fac,flim) ;
03481            mri_free(flim) ; flim = tim ;
03482          }
03483 
03484          if( MCW_val_bbox(seq->wbar_plots_bbox) != 0 ){  
03485            MEM_plotdata *mp ;
03486            if( dbg ) fprintf(stderr,"  get geometry overlay?\n") ;
03487            mp = ISQ_getmemplot( kf , seq ) ;
03488            if( mp != NULL ){
03489              if( dbg ) fprintf(stderr,"  perform geometry overlay\n") ;
03490              flip_memplot( ISQ_TO_MRI_ROT(seq->opt.rot),seq->opt.mirror,mp );
03491              memplot_to_RGB_sef( flim, mp, 0,0,MEMPLOT_FREE_ASPECT ) ;
03492              delete_memplot(mp) ;
03493            }
03494          }
03495 
03496          if( seq->wbar_label_av->ival != 0 ){  
03497            char *lab = ISQ_getlabel( kf , seq ) ;
03498            if( lab != NULL ){
03499              MEM_plotdata *mp = ISQ_plot_label( seq , lab ) ;
03500              if( mp != NULL ){
03501                memplot_to_RGB_sef( flim, mp, 0,0,MEMPLOT_FREE_ASPECT ) ;
03502                delete_memplot(mp) ;
03503              }
03504              free(lab) ;
03505            }
03506          }
03507 
03508          if( seq->zoom_fac > 1 &&                   
03509              seq->mont_nx == 1 &&                   
03510              seq->mont_ny == 1 &&
03511              AFNI_yesenv("AFNI_CROP_ZOOMSAVE") ) {
03512 
03513            int xa,ya , iw=flim->nx/seq->zoom_fac , ih=flim->ny/seq->zoom_fac ;
03514 
03515            if( dbg ) fprintf(stderr,"  crop zoomed image\n") ;
03516            xa = seq->zoom_hor_off * flim->nx ;
03517            if( xa+iw > flim->nx ) xa = flim->nx-iw ;
03518            ya = seq->zoom_ver_off * flim->nx ;
03519            if( ya+ih > flim->ny ) ya = flim->ny-ih ;
03520            tim = mri_cut_2D( flim , xa,xa+iw-1 , ya,ya+ih-1 ) ;
03521            if( tim != NULL ){ mri_free(flim); flim = tim; }
03522          }
03523 
03524          
03525 
03526          nx = flim->nx ; ny = flim->ny ; npix = nx*ny ;
03527 
03528          
03529 
03530          if( !DO_ANIM(seq) ){   
03531            if( kf == seq->saver_from )
03532               printf("writing %d x %d .%s files",nx,ny,ppmto_suffix[ff]) ;
03533            else if( kf%10 == 5 )
03534               printf("." ) ;
03535            fflush(stdout) ;
03536          }
03537 
03538          
03539 
03540          if( !DO_ANIM(seq) ){                          
03541            sprintf( fname, "%s%04d.%s", seq->saver_prefix, kf, ppmto_suffix[ff] ) ;
03542            sprintf( filt , ppmto_filter[ff] , fname ) ;
03543          } else if( DO_AGIF(seq) ){                    
03544            sprintf( fname, "%s%s.%05d.gif" , seq->saver_prefix,tsuf, kf) ;
03545 #ifndef USE_GIFF
03546            sprintf( filt , ppmto_gif_filter  , fname ) ;  
03547 #else
03548            sprintf( filt , ppmto_giff_filter , fname ) ;  
03549 #endif
03550            if( agif_list == NULL ) INIT_SARR(agif_list) ;
03551            ADDTO_SARR(agif_list,fname) ;
03552          } else if( DO_MPEG(seq) ){                    
03553            sprintf( fname, "%s%s.%05d.ppm" , seq->saver_prefix,tsuf, kf) ;
03554            sprintf( filt , ppmto_ppm_filter , fname ) ;
03555            if( agif_list == NULL ) INIT_SARR(agif_list) ;
03556            ADDTO_SARR(agif_list,fname) ;
03557          }
03558          signal( SIGPIPE , SIG_IGN ) ;                 
03559          if( dbg ) fprintf(stderr,"  piping image to '%s'\n",filt) ;
03560          fp = popen( filt , "w" ) ;                    
03561          if( fp == NULL ){
03562            fprintf(stderr,"** Can't open output filter %s\n",filt) ;
03563            continue ;  
03564          }
03565 
03566          
03567 
03568          fprintf(fp,"P6\n%d %d\n255\n" , nx,ny ) ;
03569          fwrite( MRI_RGB_PTR(flim), sizeof(byte), 3*npix, fp ) ;
03570          pc = pclose(fp) ;
03571          if( pc == -1 ) perror("Error in image output pipe") ;
03572          if( dbg ) fprintf(stderr,"  pipe done\n") ;
03573 
03574          
03575 
03576          mri_free(flim) ; flim = NULL ;
03577 
03578          
03579 
03580 
03581          if( kf == seq->saver_to && agif_list != NULL ){
03582 
03583             int af ;
03584 
03585             if( agif_list->num == 0 ){
03586                fprintf(stderr,"** Can't save animation: no images in list!\n");
03587                goto AnimationCleanup ;
03588             }
03589 
03590             
03591 
03592             if( DO_AGIF(seq) ){
03593                int alen ; char *alc , *alf , *oof ;
03594 
03595 #ifdef USE_GIFF
03596                remove( GIFF_MAPFILE ) ;   
03597 #endif
03598 
03599                for( alen=af=0 ; af < agif_list->num ; af++ ) 
03600                   alen += strlen( agif_list->ar[af] ) ;      
03601 
03602                alen += 3*agif_list->num + 32 ;               
03603                alc = AFMALL ( char, alen) ; alc[0] = '\0' ;          
03604                for( alen=af=0 ; af < agif_list->num ; af++ ){
03605                  strcat(alc," ") ; strcat(alc,agif_list->ar[af]) ;
03606                }
03607 
03608                oof  = AFMALL( char, strlen(seq->saver_prefix)+32 ) ; 
03609                sprintf(oof,"%sgif",seq->saver_prefix) ;
03610 
03611                alen =  strlen(alc)+strlen(ppmto_agif_filter)+strlen(oof)+32 ;
03612                alf  = AFMALL( char, alen) ;
03613                sprintf(alf , ppmto_agif_filter, alc, oof ) ; 
03614                fprintf(stderr,"Running '%s'\n",alf) ;
03615                system(alf) ;                                 
03616                free(alf) ; free(oof) ; free(alc) ;           
03617             }
03618 
03619             
03620 
03621             else if( DO_MPEG(seq) ){ 
03622                int alen ; char *alf , *oof , *par , *frate ;
03623                char *qscale , *pattrn ;
03624                FILE *fpar ;
03625 
03626                
03627 
03628                par = AFMALL( char, strlen(seq->saver_prefix)+32 ) ; 
03629                sprintf(par,"%s%s.PARAM",seq->saver_prefix,tsuf) ;
03630 
03631                if( dbg ) fprintf(stderr,"  creating MPEG parameter file %s\n",par) ;
03632                fpar = fopen( par , "w" ) ;
03633                if( fpar == NULL ){ free(par) ; goto AnimationCleanup ; }
03634                oof = AFMALL( char, strlen(seq->saver_prefix)+32 ) ; 
03635                sprintf(oof,"%smpg",seq->saver_prefix) ;
03636                qscale=getenv("AFNI_MPEG_QSCALE") ;if(qscale==NULL) qscale="11"   ;
03637                pattrn=getenv("AFNI_MPEG_PATTERN");if(pattrn==NULL) pattrn="IIIII";
03638                frate =getenv("AFNI_MPEG_FRAMERATE");if(frate==NULL)frate ="24"   ;
03639                fprintf(fpar,
03640                           "OUTPUT %s\n"             
03641                           "GOP_SIZE          5\n"
03642                           "SLICES_PER_FRAME  1\n"
03643                           "FRAME_RATE        %s\n"  
03644                           "BASE_FILE_FORMAT  PPM\n"
03645                           "INPUT_CONVERT     *\n"
03646                           "INPUT_DIR         .\n"
03647                           "PATTERN           %s\n"  
03648                           "IQSCALE           %s\n"  
03649                           "PQSCALE           10\n"
03650                           "BQSCALE           25\n"
03651                           "PIXEL             HALF\n"
03652                           "RANGE             10 4\n"
03653                           "PSEARCH_ALG       LOGARITHMIC\n"
03654                           "BSEARCH_ALG       SIMPLE\n"
03655                           "REFERENCE_FRAME   ORIGINAL\n"
03656                           "INPUT\n"
03657                           "%s%s.*.ppm [%05d-%05d]\n"  
03658                           "END_INPUT\n"
03659                        , oof , frate , pattrn , qscale ,
03660                          seq->saver_prefix,tsuf,seq->saver_from,seq->saver_to ) ;
03661                fclose(fpar) ;
03662 
03663                
03664 
03665                alen = strlen(par)+strlen(ppmto_mpeg_filter)+32 ;
03666                alf  = AFMALL( char, alen) ;
03667                sprintf(alf , ppmto_mpeg_filter, par ) ; 
03668                fprintf(stderr,"Running '%s' to produce %s\n",alf,oof) ;
03669                system(alf) ;                            
03670                unlink(par); free(alf); free(oof); free(par); 
03671             }
03672 
03673             
03674 
03675             for( af=0 ; af < agif_list->num ; af++ )  
03676                unlink( agif_list->ar[af] ) ;
03677 
03678           AnimationCleanup:
03679             DESTROY_SARR(agif_list) ;                 
03680          }
03681       }
03682 
03683       
03684 
03685       else if( flim->kind == MRI_rgb ){ 
03686                                         
03687          if( kf == seq->saver_from )
03688             printf("writing %d x %d RGB images",flim->nx,flim->ny) ;
03689          else if( kf%10 == 5 )
03690             printf("." ) ;
03691          fflush(stdout) ;
03692 
03693          seq->set_orim = 0 ;  
03694          tim  = flim ;
03695          flim = ISQ_process_mri( kf , seq , tim ) ;  
03696          if( tim != flim ) KILL_1MRI( tim ) ;
03697 
03698          if( AFNI_yesenv("AFNI_IMAGE_SAVESQUARE") ){   
03699            flim->dx = seq->last_dx ; flim->dy = seq->last_dy ;
03700            if( dbg ) fprintf(stderr,"  square-ate aspect ratio\n") ;
03701            tim = mri_squareaspect( flim ) ;
03702            if( tim != NULL ){ mri_free(flim); flim = tim; }
03703          }
03704 
03705          sprintf( fname , "%s%04d.pnm" , seq->saver_prefix , kf ) ;
03706          mri_write_pnm( fname , flim ) ;
03707 
03708          mri_free(flim) ; flim = NULL ; 
03709 
03710       
03711 
03712       } else if( ! seq->opt.save_pnm ){ 
03713 
03714          if( seq->opt.save_nsize ){
03715             tim = mri_nsize( flim ) ;
03716             if( tim != NULL && tim != flim ){ mri_free(flim) ; flim = tim ; }
03717          }
03718 
03719          tim  = flim ;
03720          flim = mri_flippo( ISQ_TO_MRI_ROT(seq->opt.rot) , seq->opt.mirror , tim ) ;
03721          if( tim != flim ) KILL_1MRI( tim ) ;
03722 
03723          if( kf == seq->saver_from )
03724             printf("writing %d x %d images",flim->nx,flim->ny) ;
03725          else if( kf%10 == 5 )
03726             printf("." ) ;
03727          fflush(stdout) ;
03728 
03729          if( flim->kind == MRI_byte ){  
03730             sprintf( fname , "%s%04d.pnm" , seq->saver_prefix , kf ) ;
03731             mri_write_pnm( fname , flim ) ; mri_free( flim ) ; flim = NULL ;
03732          } else {
03733             sprintf( fname , "%s%04d" , seq->saver_prefix , kf ) ;
03734             mri_write( fname , flim ) ; mri_free( flim ) ; flim = NULL ;
03735          }
03736 
03737       
03738 
03739       } else { 
03740 
03741          MRI_IMAGE * ovim=NULL ;
03742          int ii , nx , ny , npix , bb , allgray , ncode,nout ;
03743          byte * rgb ;   
03744          short * flar ;
03745          XColor * ulc , * ovc , * xc ;
03746          FILE * fd ;
03747          byte rrr,ggg,bbb ;
03748 
03749          
03750 
03751          seq->set_orim = 0 ;  
03752          tim  = flim ;
03753          flim = ISQ_process_mri( kf , seq , tim ) ;  
03754          if( tim != flim ) KILL_1MRI( tim ) ;
03755 
03756          flar = mri_data_pointer(flim) ;  
03757          nx = flim->nx ;
03758          ny = flim->ny ; npix = flim->nx * flim->ny ;
03759 
03760          
03761 
03762          if( !ISQ_SKIP_OVERLAY(seq) ){
03763             tim = ISQ_getoverlay( kf , seq ) ;
03764             if( tim != NULL && !ISQ_GOOD_OVERLAY_TYPE(tim->kind) ){
03765                KILL_1MRI(tim) ;
03766             }
03767             if( tim != NULL )
03768                ovim = mri_flippo( ISQ_TO_MRI_ROT(seq->opt.rot) , seq->opt.mirror , tim ) ;
03769             if( tim != ovim ) KILL_1MRI(tim) ;
03770          }
03771 
03772          
03773 
03774          if( ovim != NULL ){
03775 #if 1
03776             tim = flim ;
03777             flim = ISQ_overlay( seq->dc , tim , ovim , seq->ov_opacity ) ;
03778             if( flim == NULL ){ flim = tim ; }     
03779             else              { KILL_1MRI(tim) ; }
03780 #else
03781             short * ovar ; int jj ;                
03782             ovar = mri_data_pointer(ovim) ;
03783             for( jj=0 ; jj < npix ; jj++ )
03784                if( ovar[jj] != 0 ) flar[jj] = -ovar[jj] ;
03785 #endif
03786             mri_free( ovim ) ;
03787          }
03788 
03789          if( AFNI_yesenv("AFNI_IMAGE_SAVESQUARE") ){   
03790            flim->dx = seq->last_dx ; flim->dy = seq->last_dy ;
03791            tim = mri_squareaspect( flim ) ;
03792            if( tim != NULL ){ mri_free(flim); flim = tim; }
03793          }
03794 
03795          
03796 
03797          if( kf == seq->saver_from )
03798             printf("writing %d x %d PNM files",nx,ny) ;
03799          else if( kf%10 == 5 )
03800             printf("." ) ;
03801          fflush(stdout) ;
03802 
03803          sprintf( fname , "%s%04d.pnm" , seq->saver_prefix , kf ) ;
03804 
03805          if( flim->kind == MRI_rgb ){                        
03806             mri_write_pnm( fname , flim ) ; mri_free(flim) ; flim = NULL ;
03807          } else {                                            
03808 
03809             
03810 
03811             ulc = ( seq->dc->use_xcol_im ) ? seq->dc->xcol_im
03812                                            : seq->dc->xgry_im ;
03813             ovc = seq->dc->ovc->xcol_ov ;
03814 
03815             fd = fopen( fname , "r" ) ;
03816             if( fd != NULL ){
03817                fclose(fd) ;
03818                fprintf(stderr,"(FAILED) attempt to overwrite file %s\n",fname) ;
03819                continue ;
03820             }
03821             fd = fopen( fname , "w" ) ;
03822             if( fd == NULL ){
03823                fprintf(stderr,"couldn't open output file %s\n",fname) ;
03824                continue ;
03825             }
03826 
03827             
03828 
03829             rgb = (byte *) XtMalloc( sizeof(byte) * 3 * npix ) ;
03830             bb  = 0 ;
03831 
03832             allgray = 1 ;  
03833 
03834             flar = mri_data_pointer(flim) ;  
03835 
03836             for( ii=0 ; ii < npix ; ii++ ){
03837                xc  = (flar[ii] >= 0) ? (ulc+flar[ii]) : (ovc-flar[ii]) ;
03838                rrr = rgb[bb++] = INTEN_TO_BYTE( xc->red ) ;
03839                ggg = rgb[bb++] = INTEN_TO_BYTE( xc->green ) ;
03840                bbb = rgb[bb++] = INTEN_TO_BYTE( xc->blue ) ;
03841 
03842                if( allgray ) allgray = ((rrr==ggg) && (ggg==bbb)) ;
03843             }
03844 
03845             
03846 
03847             if( allgray ){
03848                bb = 3 ;
03849                for( ii=1 ; ii < npix ; ii++ ){ rgb[ii] = rgb[bb] ; bb += 3 ; }
03850                ncode = 5 ;     
03851                nout  = npix ;
03852             } else {
03853                ncode = 6 ;     
03854                nout  = 3*npix ;
03855             }
03856 
03857             fprintf(fd,"P%d\n%d %d\n255\n",ncode,nx,ny) ; 
03858             fwrite( rgb , sizeof(byte) , nout , fd ) ;         
03859             fclose( fd ); mri_free(flim); flim = NULL; myXtFree(rgb); 
03860          }
03861       }
03862    } 
03863 
03864    printf(". **DONE**\n") ; fflush(stdout) ;
03865 
03866    
03867 
03868 #ifndef DONT_USE_METER
03869    if( meter != NULL ) MCW_popdown_meter(meter) ;
03870 #endif
03871 
03872    myXtFree( seq->saver_prefix ) ; seq->saver_prefix = NULL ;
03873    EXRETURN ;
03874 }
03875 
03876 
03877 
03878 
03879 void ISQ_but_save_CB( Widget w , XtPointer client_data ,
03880                                  XtPointer call_data    )
03881 {
03882    MCW_imseq * seq = (MCW_imseq *) client_data ;
03883 
03884 ENTRY("ISQ_but_save_CB") ;
03885 
03886    if( ! ISQ_REALZ(seq) || w == NULL || ! XtIsWidget(w) ) EXRETURN ;
03887 
03888    seq->saver_prefix = NULL ;
03889    seq->saver_from = seq->saver_to = -1 ;
03890 
03891    MCW_choose_string( w , "Filename prefix:" , NULL ,
03892                       ISQ_saver_CB , (XtPointer) seq ) ;
03893 
03894    ISQ_but_done_reset( seq ) ;
03895    EXRETURN ;
03896 }
03897 
03898 
03899 
03900 
03901 
03902 #ifdef REQUIRE_TWO_DONES
03903 void ISQ_but_done_reset( MCW_imseq * seq )
03904 {
03905    if( ! ISQ_VALID(seq) || seq->done_first ) return ;
03906 
03907    MCW_set_widget_label( seq->wbut_bot[NBUT_DONE] , ISQ_but_done_label1 ) ;
03908    seq->done_first = True ;
03909    return ;
03910 }
03911 #endif
03912 
03913 
03914 
03915 
03916 
03917 void ISQ_but_done_CB( Widget w , XtPointer client_data ,
03918                                  XtPointer call_data    )
03919 {
03920    MCW_imseq * seq = (MCW_imseq *) client_data ;
03921 
03922 ENTRY("ISQ_but_done_CB") ;
03923 
03924    if( ! ISQ_VALID(seq) ) EXRETURN ;
03925 
03926 #ifdef REQUIRE_TWO_DONES
03927    
03928 
03929    if( w == seq->wbut_bot[NBUT_DONE] && seq->done_first ){
03930       MCW_set_widget_label( w , ISQ_but_done_label2 ) ;
03931       seq->done_first = False ;
03932       EXRETURN ;
03933    }
03934 #endif
03935 
03936    
03937 
03938    if( seq->glstat->worker != 0 ){  
03939       XtRemoveWorkProc( seq->glstat->worker ) ;
03940       seq->glstat->worker = 0 ;
03941    }
03942 
03943    ISQ_timer_stop(seq) ;
03944 
03945    if( seq->dialog != NULL ) XtDestroyWidget( seq->dialog ) ;  
03946 
03947    ISQ_free_alldata( seq ) ;
03948    XtDestroyWidget( seq->wtop ) ;
03949    seq->valid = 0 ;     
03950 
03951    STATUS("IMSEQ: data destroyed!") ;
03952 
03953    if( seq->status->send_CB != NULL ){
03954       ISQ_cbs cbs ;
03955 
03956       STATUS("IMSEQ: sending destroy message") ;
03957 
03958       cbs.reason = isqCR_destroy ;
03959 #if 0
03960       seq->status->send_CB( seq , seq->getaux , &cbs ) ;
03961 #else
03962       SEND(seq,cbs) ;
03963 #endif
03964    }
03965 
03966    EXRETURN ;
03967 }
03968 
03969 
03970 
03971 
03972 
03973 void ISQ_free_alldata( MCW_imseq * seq )
03974 {
03975    int ib ;
03976 
03977 ENTRY("ISQ_free_alldata") ;
03978 
03979    if( ! ISQ_VALID(seq) ) EXRETURN ;
03980 
03981    KILL_1MRI( seq->imim ) ;
03982    KILL_1MRI( seq->ovim ) ;
03983    KILL_1MRI( seq->orim ) ;  
03984 
03985    KILL_2XIM( seq->given_xim  , seq->sized_xim  ) ;
03986    KILL_2XIM( seq->given_xbar , seq->sized_xbar ) ;
03987 
03988    myXtFree( seq->imstat ) ; seq->imstat = NULL ;
03989    myXtFree( seq->glstat ) ; seq->glstat = NULL ;
03990 
03991    for( ib=0 ; ib < seq->num_bbox ; ib++ )
03992       myXtFree( seq->bbox[ib] ) ;
03993    seq->num_bbox = 0 ;
03994 
03995    for( ib=0 ; ib < NARROW ; ib++ ) myXtFree( seq->arrow[ib] ) ;
03996 
03997    myXtFree( seq->arrowpad )           ;
03998    FREE_AV( seq->mont_across_av )     ;
03999    FREE_AV( seq->mont_down_av )       ;
04000    FREE_AV( seq->mont_skip_av )       ;
04001    FREE_AV( seq->mont_gap_av )        ;
04002    FREE_AV( seq->mont_gapcolor_av )   ;
04003    FREE_AV( seq->transform0D_av )     ; 
04004    FREE_AV( seq->transform2D_av )     ;
04005    FREE_AV( seq->rowgraph_av )        ; 
04006    FREE_AV( seq->surfgraph_av )       ; 
04007    myXtFree( seq->surfgraph_arrowpad );
04008    FREE_AV( seq->ov_opacity_av )      ; 
04009    FREE_AV( seq->wbar_label_av )      ; 
04010    myXtFree( seq->wbar_plots_bbox )   ;
04011 
04012    FREE_AV( seq->wbar_labsz_av )      ; 
04013    myXtFree( seq->pen_bbox ) ;          
04014 
04015    FREE_AV( seq->slice_proj_av )      ; 
04016    FREE_AV( seq->slice_proj_range_av );
04017 
04018    FREE_AV( seq->wbar_ticnum_av )     ; 
04019    FREE_AV( seq->wbar_ticsiz_av )     ; 
04020 
04021    FREE_AV( seq->zoom_val_av ) ;
04022    if( seq->zoom_pixmap != (Pixmap) 0 ){
04023      XFreePixmap( seq->dc->display , seq->zoom_pixmap ) ;
04024      seq->zoom_pixmap = (Pixmap) 0 ;
04025    }
04026    MCW_kill_XImage( seq->zoom_xim ) ; seq->zoom_xim = NULL ;
04027 
04028    if( seq->rowgraph_mtd != NULL ){                
04029      seq->rowgraph_mtd->killfunc = NULL ;
04030      plotkill_topshell( seq->rowgraph_mtd ) ;
04031    }
04032 
04033    if( seq->surfgraph_mtd != NULL ){               
04034      seq->surfgraph_mtd->killfunc = NULL ;
04035      plotkill_topshell( seq->surfgraph_mtd ) ;
04036    }
04037 
04038    if( seq->graymap_mtd != NULL ){                 
04039      seq->graymap_mtd->killfunc = NULL ;
04040      plotkill_topshell( seq->graymap_mtd ) ;
04041    }
04042 
04043 #if 0
04044    myXtFree(seq->status) ;                         
04045 #endif
04046 
04047    
04048 
04049                    
04050    if( seq->record_mplot != NULL && seq->record_imarr != NULL ){
04051      for( ib=0 ; ib < IMARR_COUNT(seq->record_imarr) ; ib++ )
04052        delete_memplot( seq->record_mplot[ib] ) ;
04053      free((void *)seq->record_mplot) ; seq->record_mplot = NULL ;
04054    }
04055    if( seq->record_imarr != NULL ) DESTROY_IMARR(seq->record_imarr) ;
04056    if( seq->record_imseq != NULL )
04057       drive_MCW_imseq( seq->record_imseq , isqDR_destroy , NULL ) ;
04058 
04059    myXtFree( seq->record_status_bbox ) ;
04060    myXtFree( seq->record_method_bbox ) ;
04061 
04062    if( seq->mplot != NULL ){                       
04063       delete_memplot( seq->mplot ); seq->mplot = NULL;
04064    }
04065 
04066    EXRETURN ;
04067 }
04068 
04069 
04070 
04071 
04072 
04073 void ISQ_scale_CB( Widget w , XtPointer client_data , XtPointer call_data )
04074 {
04075    MCW_imseq * seq             = (MCW_imseq *)             client_data ;
04076    XmScaleCallbackStruct * cbs = (XmScaleCallbackStruct *) call_data ;
04077 
04078 ENTRY("ISQ_scale_CB") ;
04079 
04080    if( ! ISQ_REALZ(seq) ) EXRETURN ;
04081 
04082    if( seq->status->num_total < 2 ){  
04083       XmScaleSetValue( seq->wscale , 0 ) ;
04084       EXRETURN ;
04085    }
04086 
04087    ISQ_redisplay( seq , cbs->value , isqDR_display ) ;
04088 
04089    ISQ_but_done_reset( seq ) ;
04090    EXRETURN ;
04091 }
04092 
04093 
04094 
04095 
04096 
04097 
04098 
04099 
04100 
04101 
04102 
04103 
04104 
04105 
04106 
04107 
04108 
04109 
04110 
04111 
04112 
04113 
04114 
04115 
04116 
04117 
04118 
04119 
04120 #define RECUR (recur_flg && seq == recur_seq && n == recur_n)
04121 
04122 void ISQ_redisplay( MCW_imseq *seq , int n , int type )
04123 {
04124    Boolean kill_im , kill_ov ;
04125    int nrold ;
04126    static int        recur_flg = FALSE ;
04127    static int        recur_n   = -1 ;
04128    static MCW_imseq *recur_seq = NULL ;
04129 
04130    if( seq == NULL || seq->ignore_redraws ) return ;  
04131 ENTRY("ISQ_redisplay") ;
04132 
04133    if( ! ISQ_VALID(seq) ) EXRETURN ;
04134 
04135 
04136 
04137    if( RECUR ){
04138      DPRI("ABORTED FOR RECURSION at n =",n) ;
04139      recur_flg = FALSE ; EXRETURN ;
04140    }
04141 
04142 
04143 
04144 
04145 
04146 
04147    if( ! recur_flg ){ recur_flg = TRUE ; recur_n = n ; recur_seq = seq ; }
04148 
04149 
04150 
04151    nrold = seq->im_nr ;
04152 
04153 
04154 
04155    if( n >= 0 && !ISQ_set_image_number(seq,n) ){
04156       if( RECUR ) recur_flg = FALSE ; EXRETURN ;
04157    }
04158 
04159    switch( type ){
04160       default: { if( RECUR ) recur_flg = FALSE ; EXRETURN ; }
04161 
04162       case isqDR_display:
04163          kill_im = kill_ov = True ;            
04164       break ;
04165 
04166       case isqDR_overlay:
04167          kill_im = (n >=0 ) && (n != nrold) ;  
04168          kill_ov = True ;                      
04169       break ;
04170 
04171       case isqDR_reimage:
04172          kill_ov = (n >=0 ) && (n != nrold) ;
04173          kill_im = True ;
04174       break ;
04175 
04176       case isqDR_reshow:
04177          kill_ov = kill_im = (n >=0 ) && (n != nrold) ; 
04178       break ;
04179    }
04180 
04181    if( kill_im ) KILL_1MRI( seq->imim ) ;
04182    if( kill_ov ) KILL_1MRI( seq->ovim ) ;
04183 
04184    if( kill_ov || kill_im ) KILL_2XIM( seq->given_xim , seq->sized_xim  ) ;
04185 
04186    if( kill_ov || kill_im ){
04187       MCW_kill_XImage( seq->zoom_xim ) ; seq->zoom_xim = NULL ;
04188    }
04189 
04190    ISQ_show_image( seq ) ;
04191    ISQ_rowgraph_draw( seq ) ;
04192    ISQ_surfgraph_draw( seq ) ;  
04193 
04194    if( seq->graymap_mtd != NULL ) ISQ_graymap_draw( seq ) ; 
04195 
04196    
04197 
04198    if( RECORD_ISON(seq->record_status) && seq->zoom_fac == 1 ){
04199       int pos , meth ;
04200 
04201       
04202 
04203       switch( seq->record_method ){
04204          default:
04205          case RECORD_METHOD_AFTEREND:     pos = 987654321; meth =  1; break;
04206          case RECORD_METHOD_BEFORESTART:  pos =  0       ; meth = -1; break;
04207          case RECORD_METHOD_INSERT_MM:    pos = -1       ; meth = -1; break;
04208          case RECORD_METHOD_INSERT_PP:    pos = -1       ; meth =  1; break;
04209          case RECORD_METHOD_OVERWRITE:    pos = -1       ; meth =  0; break;
04210          case RECORD_METHOD_OVERWRITE_MM: pos = -2       ; meth =  0; break;
04211          case RECORD_METHOD_OVERWRITE_PP: pos = -3       ; meth =  0; break;
04212       }
04213 
04214       
04215 
04216       ISQ_record_addim( seq , pos , meth ) ;
04217 
04218       
04219 
04220       if( seq->record_status == RECORD_STATUS_NEXTONE ){
04221          seq->record_status = RECORD_STATUS_OFF ;
04222          MCW_set_bbox( seq->record_status_bbox , RECORD_STATUS_OFF ) ;
04223          MCW_invert_widget( seq->record_cbut ) ;
04224       }
04225    }
04226 
04227    
04228 
04229    if( RECUR ) recur_flg = FALSE ;
04230    EXRETURN ;
04231 }
04232 
04233 
04234 
04235 
04236 
04237 
04238 int ISQ_set_image_number( MCW_imseq * seq , int n )
04239 {
04240 ENTRY("ISQ_set_image_number") ;
04241 
04242    if( ! ISQ_VALID(seq) ) RETURN(0) ;
04243 
04244    if( n < 0 || n >= seq->status->num_total ){
04245 
04246      if( seq->status->num_total > 1 ){
04247        XBell( seq->dc->display , 100 ) ;
04248        fprintf(stderr,"\n*** ILLEGAL IMAGING:\n"
04249                       " ISQ_set_image_number %d\n",n);
04250 
04251        fprintf(stderr," status: num_total=%d num_series=%d\n",
04252                seq->status->num_total , seq->status->num_series ) ;
04253      } else {
04254        XmScaleSetValue( seq->wscale , 0 ) ;  
04255      }
04256 
04257      RETURN(0) ;
04258    }
04259 
04260    if( seq->im_nr != n ){
04261      XmScaleSetValue( seq->wscale , n ) ;  
04262 
04263      if( seq->status->send_CB != NULL ){
04264        ISQ_cbs cbs ;
04265        seq->im_nr = n ;
04266        cbs.reason = isqCR_newimage ;
04267        cbs.nim    = seq->im_nr ;
04268 #if 0
04269        seq->status->send_CB( seq , seq->getaux , &cbs ) ;
04270 #else
04271        SEND(seq,cbs) ;
04272 #endif
04273      } else {
04274 #if 0
04275        ISQ_redisplay( seq , n , isqDR_display ) ;  
04276 #endif
04277      }
04278    }
04279    RETURN(1) ;
04280 }
04281 
04282 
04283 
04284 
04285 
04286 static volatile int xwasbad ;
04287 typedef int (*xhandler)(Display *, XErrorEvent *) ;
04288 static int qhandler( Display *dpy , XErrorEvent *xev ){ xwasbad=1; return 0; }
04289 
04290 
04291 
04292 int ISQ_show_zoom( MCW_imseq *seq )   
04293 {
04294    int iw,ih , zlev=seq->zoom_fac , pw,ph , xoff,yoff , newim=0 , flash=0 ;
04295    static int busy=0 ;                
04296 
04297 ENTRY("ISQ_show_zoom") ;
04298 
04299    if( busy ){ STATUS(" recursive entry!"); RETURN(-1); }          
04300    busy = 1 ;
04301 
04302    
04303 
04304    MCW_widget_geom( seq->wimage, &iw,&ih , NULL,NULL ) ;
04305 
04306    
04307 
04308 
04309    pw = iw*zlev ; ph = ih*zlev ;
04310 
04311    if( seq->zoom_pixmap != (Pixmap) 0 &&
04312        (pw != seq->zoom_pw || ph != seq->zoom_ph) ){
04313 
04314 STATUS("freeing old pixmap") ;
04315       XFreePixmap( seq->dc->display , seq->zoom_pixmap ) ;
04316       seq->zoom_pixmap = (Pixmap) 0 ;
04317       newim++ ;
04318    }
04319 
04320    
04321 
04322 
04323    if( seq->zoom_pixmap == (Pixmap) 0 ){
04324       xhandler old_handler = XSetErrorHandler(qhandler); xwasbad = 0;
04325 
04326 STATUS("creating new pixmap") ;
04327       seq->zoom_pixmap = XCreatePixmap( seq->dc->display ,
04328                                         XtWindow(seq->wimage) ,
04329                                         pw , ph , seq->dc->depth ) ;
04330 
04331       (void) XSetErrorHandler(old_handler) ;
04332 
04333       
04334 
04335       if( xwasbad ){
04336         fprintf(stderr,"** Can't zoom - out of memory! **\n\a");
04337         AV_assign_ival( seq->zoom_val_av , 1 ) ;
04338         ISQ_zoom_av_CB( seq->zoom_val_av , seq ) ;
04339         busy = 0 ; RETURN(-1) ;
04340       }
04341 
04342       seq->zoom_pw = pw ; seq->zoom_ph = ph ;
04343       newim++ ;
04344    }
04345 
04346    
04347 
04348    if( newim && seq->zoom_xim != NULL ){
04349 STATUS("killing old XImage because have new image") ;
04350      MCW_kill_XImage( seq->zoom_xim ) ; seq->zoom_xim = NULL ;
04351    }
04352 
04353    
04354 
04355 
04356 
04357 
04358    if( seq->zoom_xim == NULL ){
04359      MRI_IMAGE *im , *tim ;
04360 STATUS("inverting zoom label") ;
04361      flash = 1 ; MCW_invert_widget( seq->zoom_val_av->wlabel ) ;
04362 STATUS("converting given XImage to MRI_IMAGE") ;
04363      im  = XImage_to_mri( seq->dc, seq->given_xim, X2M_USE_CMAP|X2M_FORCE_RGB ) ;
04364 STATUS("zooming up MRI_IMAGE") ;
04365      tim = mri_dup2D(zlev,im) ; mri_free(im) ;
04366 STATUS("converting zoomed MRI_IMAGE back to XImage") ;
04367      seq->zoom_xim = mri_to_XImage(seq->dc,tim) ; mri_free(tim) ;
04368      newim++ ;
04369    }
04370 
04371    
04372 
04373    if( pw != seq->zoom_xim->width || ph != seq->zoom_xim->height ){
04374      XImage *sxim ;
04375      sxim = resize_XImage( seq->dc , seq->zoom_xim , pw , ph ) ;
04376 STATUS("killing old XImage because doesn't fit pixmap") ;
04377      MCW_kill_XImage( seq->zoom_xim ) ;
04378      seq->zoom_xim = sxim ;
04379      newim++ ;
04380    }
04381 
04382    
04383 
04384    if( newim ){
04385 STATUS("putting new image into pixmap") ;
04386      XPutImage( seq->dc->display ,
04387                 seq->zoom_pixmap ,
04388                 seq->dc->origGC  , seq->zoom_xim , 0,0,0,0 , pw,ph ) ;
04389 
04390      
04391 
04392      if( !seq->opt.no_overlay && seq->mplot != NULL ){
04393 STATUS("drawing overlay plot into pixmap") ;
04394         memplot_to_X11_sef( seq->dc->display ,
04395                             seq->zoom_pixmap , seq->mplot ,
04396                             0,0,MEMPLOT_FREE_ASPECT        ) ;
04397      }
04398    }
04399 
04400    
04401 
04402 
04403    xoff = seq->zoom_hor_off * pw ; if( xoff+iw > pw ) xoff = pw-iw ;
04404    yoff = seq->zoom_ver_off * ph ; if( yoff+ih > ph ) yoff = ph-ih ;
04405 
04406 STATUS("copying from pixmap to image window") ;
04407    XCopyArea( seq->dc->display ,
04408               seq->zoom_pixmap ,
04409               XtWindow(seq->wimage) , seq->dc->origGC ,
04410               xoff , yoff , iw,ih , 0,0 ) ;
04411 
04412    if( flash ) MCW_invert_widget( seq->zoom_val_av->wlabel ) ;
04413 
04414 #ifdef DISCARD_EXCESS_EXPOSES
04415 STATUS("discarding excess Expose events") ;
04416     MCW_discard_events( seq->wimage , ExposureMask ) ;
04417 #endif
04418 
04419    busy = 0 ; RETURN(1) ;
04420 }
04421 
04422 
04423 
04424 
04425 
04426 
04427 
04428 void ISQ_show_image( MCW_imseq *seq )
04429 {
04430    if( seq == NULL || seq->ignore_redraws ) return ;  
04431 ENTRY("ISQ_show_image") ;
04432 
04433    if( ! ISQ_REALZ(seq) ) EXRETURN ;
04434 
04435    if( seq->given_xbar == NULL ) ISQ_show_bar( seq ) ;  
04436 
04437    if( seq->given_xim == NULL ) ISQ_make_image( seq ) ;
04438 
04439    if( seq->given_xim == NULL ) STATUS("bad news: given_xim == NULL!") ;
04440 
04441    if( ! MCW_widget_visible(seq->wimage) ) EXRETURN ;  
04442 
04443    if( seq->given_xim != NULL &&
04444        seq->zoom_fac  >  1    &&
04445        seq->mont_nx   == 1    &&
04446        seq->mont_ny   == 1      ){    
04447 
04448       int ss = ISQ_show_zoom( seq ) ;
04449       if( ss > 0 ) EXRETURN ;         
04450    }
04451 
04452    if( seq->given_xim != NULL && seq->sized_xim == NULL ){
04453       int nx , ny ;
04454 
04455       STATUS("making sized_xim");
04456 
04457       MCW_widget_geom( seq->wimage , &nx , &ny , NULL,NULL ) ;
04458 
04459       seq->sized_xim = resize_XImage( seq->dc , seq->given_xim , nx , ny ) ;
04460    }
04461 
04462    if( seq->sized_xim != NULL ){
04463 DPR("putting sized_xim to screen");
04464 
04465 #if 0
04466 if( AFNI_yesenv("AFNI_IMSEQ_DEBUG") ){
04467   fprintf(stderr,"==== imseq->wimage: XPutImage w=%d h=%d\n",
04468   seq->sized_xim->width , seq->sized_xim->height ) ;
04469   DBG_traceback() ;
04470 }
04471 #endif
04472 
04473      XPutImage( seq->dc->display , XtWindow(seq->wimage) , seq->dc->origGC ,
04474                 seq->sized_xim , 0,0,0,0,
04475                 seq->sized_xim->width , seq->sized_xim->height ) ;
04476 
04477    } else {  
04478 
04479       static MEM_plotdata *empt=NULL ;  
04480 
04481       if( empt == NULL ){
04482          STATUS("create EMPTY IMAGE plot") ;
04483          create_memplot_surely("EmptyImagePlot",1.0) ;
04484          empt = get_active_memplot() ;
04485          set_color_memplot(1.0,1.0,1.0) ;
04486          set_thick_memplot(0.009) ;
04487          plotpak_pwritf( 0.4,0.83 , "EMPTY" , 96 , 0 , 0 ) ;
04488          plotpak_pwritf( 0.4,0.67 , "IMAGE" , 96 , 0 , 0 ) ;
04489          set_color_memplot(0.0,0.0,0.0) ;
04490          plotpak_pwritf( 0.6,0.33 , "EMPTY" , 96 , 0 , 0 ) ;
04491          plotpak_pwritf( 0.6,0.17 , "IMAGE" , 96 , 0 , 0 ) ;
04492          set_color_memplot(1.0,1.0,0.0) ;
04493          set_thick_memplot(0.019) ;
04494          plotpak_line( 0.01,0.01 , 0.99,0.01 ) ;
04495          plotpak_line( 0.99,0.01 , 0.99,0.99 ) ;
04496          plotpak_line( 0.99,0.99 , 0.01,0.99 ) ;
04497          plotpak_line( 0.01,0.99 , 0.01,0.01 ) ;
04498          set_thick_memplot(0.0) ;
04499       }
04500       STATUS("display EMPTY IMAGE plot") ;
04501       XClearWindow( seq->dc->display , XtWindow(seq->wimage) ) ;
04502       memplot_to_X11_sef( seq->dc->display ,
04503                           XtWindow(seq->wimage) , empt ,
04504                           0,0,MEMPLOT_FREE_ASPECT     ) ;
04505    }
04506 
04507    
04508    
04509 
04510    if( !seq->opt.no_overlay && seq->mplot != NULL )
04511       memplot_to_X11_sef( seq->dc->display ,
04512                           XtWindow(seq->wimage) , seq->mplot ,
04513                           0,0,MEMPLOT_FREE_ASPECT             ) ;
04514 
04515    seq->never_drawn = 0 ;
04516 
04517    ISQ_draw_winfo( seq ) ;
04518 
04519 #ifdef DISCARD_EXCESS_EXPOSES
04520     MCW_discard_events( seq->wimage , ExposureMask ) ;
04521 #endif
04522 
04523    EXRETURN ;
04524 }
04525 
04526 
04527 
04528 
04529 
04530 void ISQ_draw_winfo( MCW_imseq * seq )
04531 {
04532    char buf[128] = "\0" ;
04533    int nn , ibuf ;
04534    ISQ_indiv_statistics * st ;
04535 
04536 ENTRY("ISQ_draw_winfo") ;
04537 
04538    if( ! ISQ_REALZ(seq) ) EXRETURN ;
04539 
04540    if( seq->last_image_type >= 0 ){
04541      sprintf( buf , "%s" , MRI_TYPE_name[seq->last_image_type] ) ;
04542 
04543      if( seq->last_image_type == MRI_complex ){
04544        switch( seq->opt.cx_code ){
04545          case ISQ_CX_MAG:   strcat( buf , "[mag]"  ) ; break ;
04546          case ISQ_CX_PHASE: strcat( buf , "[arg]"  ) ; break ;
04547          case ISQ_CX_REAL:  strcat( buf , "[real]" ) ; break ;
04548          case ISQ_CX_IMAG:  strcat( buf , "[imag]" ) ; break ;
04549        }
04550      }
04551    }
04552    ibuf = strlen(buf) ;
04553 
04554    nn = seq->im_nr ;  if( nn < 0 ) EXRETURN ;
04555    st = &( seq->imstat[nn] ) ;
04556    if( st->one_done ){
04557 #if 0
04558       if( seq->opt.scale_group == ISQ_SCL_AUTO   &&
04559           seq->opt.scale_range == ISQ_RNG_02TO98    )
04560 
04561            sprintf( buf+ibuf , " 2%%=%g 98%%=%g", st->per02 , st->per98 ) ;
04562       else
04563 #endif
04564            sprintf( buf+ibuf , "=%g..%g ent=%.2f" ,
04565                     st->min , st->max , st->entropy ) ;
04566    }
04567 
04568    if( seq->im_label[0] == '\0' || strcmp(buf,seq->im_label) != 0 ){
04569      if( seq->winfo_extra[0] == '\0' ){
04570 
04571        int iw=0 ;                                   
04572        switch( seq->opt.rot ){                      
04573          case ISQ_ROT_0  : iw=0 ; break ;
04574          case ISQ_ROT_90 : iw=1 ; break ;
04575          case ISQ_ROT_180: iw=2 ; break ;
04576          case ISQ_ROT_270: iw=3 ; break ;
04577        }
04578        if( seq->opt.mirror ) iw = (iw+2)%4 ;
04579 
04580        if( seq->winfo_sides[iw][0] != '\0' ){
04581          char qbuf[128] ;
04582          strcpy(qbuf,"left=") ;
04583          strcat(qbuf,seq->winfo_sides[iw]) ;
04584          strcat(qbuf," ") ; strcat(qbuf,buf) ;
04585          MCW_set_widget_label( seq->winfo , qbuf ) ;
04586        } else {
04587          MCW_set_widget_label( seq->winfo , buf ) ;   
04588        }
04589 
04590      } else {                                        
04591        char qbuf[128] ;                             
04592        strcpy(qbuf,seq->winfo_extra) ;
04593        strcat(qbuf," ") ; strcat(qbuf,buf) ;
04594        MCW_set_widget_label( seq->winfo , qbuf ) ;
04595      }
04596      strcpy(seq->im_label,buf) ;
04597    }
04598 
04599    EXRETURN ;
04600 }
04601 
04602 
04603 
04604 
04605 
04606 void ISQ_set_barhint( MCW_imseq * seq , char * lab )
04607 {
04608    char sbot[16],stop[16] , hint[64] , *sb,*st ;
04609 
04610 ENTRY("ISQ_set_barhint") ;
04611 
04612    if( !ISQ_REALZ(seq) ) EXRETURN ;            
04613 
04614    if( seq->barbot < seq->bartop ){            
04615       AV_fval_to_char( seq->barbot , sbot ) ;  
04616       AV_fval_to_char( seq->bartop , stop ) ;
04617       sb = (sbot[0] == ' ') ? sbot+1 : sbot ;  
04618       st = (stop[0] == ' ') ? stop+1 : stop ;
04619       if( lab != NULL && strlen(lab) < 32 )    
04620          sprintf(hint,"%s: %s .. %s",lab,sb,st) ;
04621       else
04622          sprintf(hint,"%s .. %s",sb,st) ;
04623       MCW_register_hint( seq->wbar , hint ) ;  
04624    } else {
04625       MCW_unregister_hint( seq->wbar ) ;       
04626    }
04627 
04628    EXRETURN ;
04629 }
04630 
04631 
04632 
04633 void ISQ_set_cursor_state( MCW_imseq *seq , int cstat )  
04634 {
04635    if( seq->zoom_button1 || seq->record_mode ){
04636      XBell(seq->dc->display,100); return;
04637    }
04638 
04639 #if 0
04640 fprintf(stderr,"ISQ_set_cursor_state: old=%d new=%d\n",seq->cursor_state,cstat);
04641 #endif
04642 
04643    switch( cstat ){
04644      default:
04645        POPUP_cursorize( seq->wimage ) ;
04646        seq->cursor_state = CURSOR_NORMAL ;
04647        MCW_set_bbox( seq->pen_bbox , 0 ) ;
04648      break ;
04649 
04650      case CURSOR_PENCIL:
04651        PENCIL_cursorize( seq->wimage ) ;
04652        seq->cursor_state = CURSOR_PENCIL ;
04653        MCW_set_bbox( seq->pen_bbox , 1 ) ;
04654      break ;
04655 
04656      case CURSOR_CROSSHAIR:
04657        CROSSHAIR_cursorize( seq->wimage ) ;
04658        seq->cursor_state = CURSOR_CROSSHAIR ;
04659        MCW_set_bbox( seq->pen_bbox , 0 ) ;
04660      break ;
04661    }
04662    return ;
04663 }
04664 
04665 
04666 
04667 
04668 
04669 void ISQ_show_bar( MCW_imseq * seq )
04670 {
04671    if( seq == NULL || seq->ignore_redraws ) return ;  
04672 ENTRY("ISQ_show_bar") ;
04673 
04674    if( ! ISQ_REALZ(seq) ) EXRETURN ;
04675 
04676    if( ! MCW_widget_visible(seq->wbar) ) EXRETURN ;  
04677 
04678    if( seq->given_xbar == NULL ) ISQ_make_bar( seq ) ;
04679 
04680    if( seq->sized_xbar == NULL ){
04681       int nx , ny ;
04682 DPR("making sized_xbar");
04683 
04684       MCW_widget_geom( seq->wbar , &nx , &ny , NULL,NULL ) ;
04685 
04686       seq->sized_xbar = resize_XImage( seq->dc, seq->given_xbar, nx, ny ) ;
04687    }
04688 
04689 
04690    if( seq->sized_xbar != NULL ){
04691 DPR("putting sized_xbar to screen");
04692 
04693      XPutImage( seq->dc->display , XtWindow(seq->wbar) , seq->dc->origGC ,
04694                 seq->sized_xbar , 0,0,0,0,
04695                 seq->sized_xbar->width , seq->sized_xbar->height ) ;
04696    }
04697 
04698 #ifdef DISCARD_EXCESS_EXPOSES
04699     MCW_discard_events( seq->wbar , ExposureMask ) ;
04700 #endif
04701 
04702    EXRETURN ;
04703 }
04704 
04705 
04706 
04707 
04708 
04709 
04710 void ISQ_drawing_EV( Widget w , XtPointer client_data ,
04711                      XEvent * ev , Boolean * continue_to_dispatch )
04712 {
04713    MCW_imseq * seq = (MCW_imseq *) client_data ;
04714    static ISQ_cbs cbs ;
04715    static int busy=0 ;   
04716 
04717 ENTRY("ISQ_drawing_EV") ;
04718 
04719    if( busy ){ STATUS("recursive entry!"); EXRETURN; }  
04720    if( !ISQ_REALZ(seq) ) EXRETURN ;
04721    busy = 1 ;
04722 
04723    if(PRINT_TRACING){
04724      char str[256], *wn ;
04725           if( w == seq->wimage ) wn = "wimage" ;
04726      else if ( w == seq->wbar  ) wn = "wbar"   ;
04727      else                        wn = XtName(w) ;
04728      sprintf(str,"Widget=%s Event type=%d",wn,ev->type);
04729      STATUS(str) ;
04730    }
04731 
04732    switch( ev->type ){
04733 
04734       
04735 
04736       case ButtonRelease:{
04737          XButtonEvent * event = (XButtonEvent *) ev ;
04738          int but = event->button ;
04739 
04740 
04741 
04742          if( but == Button1 &&
04743              ( seq->cursor_state == CURSOR_PENCIL ||
04744                ((event->state & ShiftMask) && !(event->state & ControlMask)) ) ){
04745            event->button = but = Button2 ;
04746            if( seq->button2_enabled && w == seq->wimage )
04747               ISQ_button2_EV( w , client_data , ev , continue_to_dispatch ) ;
04748            else
04749               { XBell(seq->dc->display,100); busy=0;EXRETURN; }
04750          }
04751 
04752          
04753 
04754          if( event->button == Button1 && w == seq->wimage ){
04755 
04756            if( seq->zoom_button1 && !AFNI_yesenv("AFNI_KEEP_PANNING") ){
04757              seq->zoom_button1 = 0 ;
04758              POPUP_cursorize( seq->wimage ) ;
04759              MCW_invert_widget( seq->zoom_drag_pb ) ;
04760            } else if( !seq->zoom_button1 ){           
04761              if( seq->cmap_changed ){
04762                COLORMAP_CHANGE(seq); seq->cmap_changed = 0;
04763                if( seq->graymap_mtd != NULL && AFNI_yesenv("AFNI_STROKE_AUTOPLOT") ){
04764                  RWC_sleep(456) ;     
04765                  plotkill_topshell( seq->graymap_mtd ) ;
04766                  seq->graymap_mtd = NULL ;
04767                }
04768              } else if( seq->status->send_CB != NULL ){  
04769                 int imx,imy,nim;
04770                 seq->wimage_width = -1 ;
04771                 ISQ_mapxy( seq , seq->last_bx,seq->last_by , &imx,&imy,&nim ) ;
04772                 cbs.reason = isqCR_buttonpress ;
04773                 cbs.event  = ev ;
04774                 cbs.xim    = imx ;       
04775                 cbs.yim    = imy ;       
04776                 cbs.nim    = nim ;
04777 #if 0
04778                 seq->status->send_CB( seq , seq->getaux , &cbs ) ;
04779 #else
04780                 SEND(seq,cbs) ;
04781 #endif
04782              }
04783            }
04784          }
04785       }
04786       break ;
04787 
04788       
04789 
04790       case MotionNotify:{
04791         XMotionEvent * event = (XMotionEvent *) ev ;
04792         int bx,by ;
04793 
04794 
04795 
04796         if( (event->state & Button1Mask) &&
04797              ( seq->cursor_state == CURSOR_PENCIL ||
04798                ((event->state & ShiftMask) && !(event->state & ControlMask)) ) ){
04799           event->state |= Button2Mask ;
04800           if( seq->button2_enabled && w == seq->wimage )
04801              ISQ_button2_EV( w , client_data , ev , continue_to_dispatch ) ;
04802           else
04803              { XBell(seq->dc->display,100); busy=0;EXRETURN; }
04804           busy=0;EXRETURN ;
04805         }
04806 
04807         
04808 
04809         if( !seq->zoom_button1 && (event->state & Button1Mask) ){
04810           int xdif = (event->x - seq->last_bx) ;
04811           int ydif = (event->y - seq->last_by) ;
04812           if( !seq->dc->use_xcol_im && (xdif || ydif) ){
04813             double denom = AFNI_numenv("AFNI_STROKE_THRESHOLD") ;
04814             if( denom < 1.0l ){
04815               if( getenv("AFNI_STROKE_THRESHOLD") != NULL ){ busy=0;EXRETURN ;}
04816               denom = 32.0l ;
04817             }
04818             xdif = rint(xdif/denom) ; ydif = rint(ydif/denom) ;
04819             if( xdif || ydif ){                             
04820               if( seq->imim != NULL && seq->imim->kind == MRI_rgb ){ 
04821 
04822                      if( xdif > 0 ) seq->rgb_gamma  *= 0.95 ;  
04823                 else if( xdif < 0 ) seq->rgb_gamma  /= 0.95 ;      
04824                      if( ydif < 0 ) seq->rgb_offset += 0.014;
04825                 else if( ydif > 0 ) seq->rgb_offset -= 0.014;
04826                 ISQ_redisplay( seq , -1 , isqDR_reimage ) ;
04827                 seq->cmap_changed = 1 ;
04828                 seq->last_bx=event->x ; seq->last_by=event->y;
04829 
04830               } else {                          
04831 
04832                 if( xdif ){ DC_gray_conbrio(seq->dc, xdif); seq->last_bx=event->x;}
04833                 if( ydif ){ DC_gray_change (seq->dc,-ydif); seq->last_by=event->y;}
04834                 seq->cmap_changed = 1 ;
04835                 if( seq->dc->visual_class == TrueColor ){
04836                   if( seq->graymap_mtd == NULL &&
04837                       AFNI_yesenv("AFNI_STROKE_AUTOPLOT") ) ISQ_graymap_draw( seq ) ;
04838                   KILL_2XIM( seq->given_xbar , seq->sized_xbar ) ;
04839                   ISQ_redisplay( seq , -1 , isqDR_display ) ;
04840                 } else {
04841                   if( seq->graymap_mtd != NULL ) ISQ_graymap_draw( seq ) ;
04842                 }
04843               }
04844             }
04845           }
04846           busy=0; EXRETURN ;
04847         }  
04848 
04849         
04850 
04851         if( !seq->zoom_button1              ||
04852             seq->zoom_fac == 1              ||
04853             seq->zoom_xim == NULL           ||
04854             (event->state & Button1Mask)==0   ){ busy=0; EXRETURN; } 
04855 
04856         
04857 
04858         bx = event->x ; by = event->y ;
04859         ISQ_actually_pan( seq , (bx>seq->zoom_xp) ? -1
04860                                :(bx<seq->zoom_xp) ?  1 : 0 ,
04861                                 (by>seq->zoom_yp) ? -1
04862                                :(by<seq->zoom_yp) ?  1 : 0   ) ;
04863 
04864         seq->zoom_xp = bx ; seq->zoom_yp = by ;
04865 
04866         busy=0; EXRETURN ;
04867       }
04868       break ;
04869 
04870       
04871 
04872       case Expose:{
04873          XExposeEvent * event = (XExposeEvent *) ev ;
04874 
04875 DPRI(" .. Expose; count=",event->count) ;
04876 
04877          XSync( XtDisplay(w) , False ) ;
04878          if( event->count == 0 ){      
04879             if( w == seq->wimage ){    
04880                int nx,ny ;
04881                MCW_widget_geom( seq->wimage , &nx , &ny , NULL,NULL ) ;
04882 
04883                if( seq->sized_xim != NULL &&
04884                    ( (nx != seq->sized_xim->width ) ||
04885                      (ny != seq->sized_xim->height)   ) ){  
04886                                                             
04887                   XConfigureEvent nev ;
04888 
04889 DPR(" .. really a hidden resize") ;
04890 
04891                   nev.type = ConfigureNotify ; nev.width = nx ; nev.height = ny ;
04892                   ISQ_drawing_EV( w, client_data, (XEvent *) &nev, continue_to_dispatch ) ;
04893 
04894                } else
04895                   ISQ_show_image( seq ) ;
04896             }
04897             else if( w == seq->wbar )
04898                ISQ_show_bar( seq ) ;
04899 
04900          }
04901       }
04902       break ;
04903 
04904       
04905 
04906       case KeyPress:{
04907          XKeyEvent *event = (XKeyEvent *) ev ;
04908          char       buf[32] ;
04909          int        nbuf ;
04910          KeySym     ks ;
04911 
04912 DPR(" .. KeyPress") ;
04913 
04914          ISQ_timer_stop(seq) ;  
04915 
04916          
04917 
04918          if( event->state & (Button1Mask|Button2Mask|Button3Mask) ){
04919            XBell(seq->dc->display,100); busy=0; EXRETURN;
04920          }
04921 
04922          
04923 
04924          buf[0] = '\0' ;
04925          ks     = 0 ;
04926          nbuf = XLookupString( event , buf , 32 , &ks , NULL ) ;
04927 #if 0
04928 fprintf(stderr,"KeySym=%04x nbuf=%d\n",(unsigned int)ks,nbuf) ;
04929 #endif
04930 
04931          
04932 
04933          if( nbuf == 0 || ks > 255 ){
04934            if( seq->record_mode ){ busy=0; EXRETURN ; }
04935            nbuf = ISQ_handle_keypress( seq , (unsigned long)ks ) ;
04936            busy=0; EXRETURN ;
04937          }
04938 
04939          nbuf = ISQ_handle_keypress( seq , (unsigned long)buf[0] ) ;
04940          if( nbuf ){ busy=0; EXRETURN; }
04941 
04942          
04943 
04944          if( seq->record_mode || seq->button2_active || seq->zoom_button1 ){
04945            XBell(seq->dc->display,100); busy=0; EXRETURN;
04946          }
04947 
04948          
04949 
04950          if( w == seq->wimage && seq->status->send_CB != NULL ){
04951            cbs.reason = isqCR_keypress ;
04952            cbs.event  = ev ;
04953            cbs.key    = buf[0] ;
04954            cbs.nim    = seq->im_nr ;
04955 #if 0
04956            seq->status->send_CB( seq , seq->getaux , &cbs ) ;
04957 #else
04958            SEND(seq,cbs) ;
04959 #endif
04960          }
04961       }
04962       break ;  
04963 
04964       
04965 
04966       case ButtonPress:{
04967          XButtonEvent * event = (XButtonEvent *) ev ;
04968          int bx,by , width,height , but ;
04969 
04970 DPR(" .. ButtonPress") ;
04971 
04972          
04973 
04974          if( seq->record_mode || seq->zoom_button1 ){
04975            if( seq->record_mode || event->button != Button1 ) XBell(seq->dc->display,100);
04976            busy=0; EXRETURN;
04977          }
04978 
04979          
04980 
04981          if( w == seq->wbar ){          
04982            if( event->button == Button1 ){ 
04983              bx = seq->opt.free_aspect ; seq->opt.free_aspect = 0 ;
04984              ISQ_reset_dimen( seq, seq->last_width_mm, seq->last_height_mm ) ;
04985              seq->opt.free_aspect = bx ;
04986            } else if( event->button == Button3 ){
04987              XmMenuPosition( seq->wbar_menu , event ) ; 
04988              XtManageChild ( seq->wbar_menu ) ;         
04989            }
04990            else
04991 #if 0
04992              XUngrabPointer( event->display , CurrentTime ) ;
04993 #else
04994              XBell(seq->dc->display,100) ;
04995 #endif
04996            busy=0; EXRETURN ;
04997          }
04998 
04999          
05000 
05001          seq->last_bx = bx = event->x ;  
05002          seq->last_by = by = event->y ;  
05003          seq->cmap_changed = 0 ;
05004          but = event->button ;
05005 
05006          MCW_widget_geom( w , &width , &height , NULL,NULL ) ;
05007          seq->wimage_width  = width ;
05008          seq->wimage_height = height ;
05009 
05010          MCW_discard_events( w , ButtonPressMask ) ;
05011 
05012          
05013 
05014          if( w == seq->wimage &&
05015              ( (but==Button2 && (event->state & ShiftMask)) ||
05016                (seq->crop_drag)                            )  ){
05017 
05018            ISQ_cropper( seq , event ) ;
05019            busy=0; EXRETURN ;
05020 
05021          } 
05022 
05023 
05024 
05025          if( but == Button1 &&
05026              ( seq->cursor_state == CURSOR_PENCIL ||
05027                ((event->state & ShiftMask) && !(event->state & ControlMask)) ) )
05028            event->button = but = Button2 ;
05029 
05030          
05031 
05032          switch( but ){
05033 
05034             case Button3:
05035             case Button1:{
05036               int imx,imy,nim;
05037 
05038               
05039 
05040               if( seq->button2_active ){
05041                 
05042                 busy=0; EXRETURN ;
05043               }
05044 
05045               
05046 
05047 
05048               if( w == seq->wimage && but == Button3 &&
05049                   (event->state & (ShiftMask|ControlMask|Mod1Mask)) ){
05050 
05051                 
05052 
05053                 if( (event->state & ShiftMask) && !(event->state & ControlMask) )
05054                   ISQ_but_disp_CB( seq->wbut_bot[NBUT_DISP] , seq , NULL ) ;
05055 
05056                 else if( (event->state & ControlMask) ){
05057                   if( seq->status->num_total > 1 && !(event->state & ShiftMask) ){
05058                     ISQ_montage_CB( seq->wbut_bot[NBUT_MONT] , seq , NULL ) ;
05059                   } else {
05060                     XmMenuPosition( seq->wbar_menu , event ) ;
05061                     XtManageChild ( seq->wbar_menu ) ;
05062                   }
05063                 }
05064 
05065                 else if( (seq->opt.save_one || seq->status->num_total > 1)
05066                          && (event->state & Mod1Mask) )
05067                    ISQ_but_save_CB( seq->wbut_bot[NBUT_SAVE] , seq , NULL ) ;
05068 
05069                 else
05070                    XBell( seq->dc->display , 100 ) ;
05071 
05072               
05073 
05074 
05075               } else if( w == seq->wimage && seq->status->send_CB != NULL ){
05076 
05077                 seq->wimage_width = -1 ;
05078                 ISQ_mapxy( seq , bx,by , &imx,&imy,&nim ) ;
05079                 cbs.reason = isqCR_buttonpress ;
05080                 cbs.event  = ev ;
05081                 cbs.xim    = imx ;
05082                 cbs.yim    = imy ;
05083                 cbs.nim    = nim ;
05084 
05085                 if( but == Button1 &&
05086                     (event->state & ControlMask) ){ 
05087                    event->button = Button3 ;        
05088                 }
05089 
05090                 if( event->button == Button3 )      
05091 #if 0
05092                   seq->status->send_CB( seq , seq->getaux , &cbs ) ;
05093 #else
05094                   SEND(seq,cbs) ;
05095 #endif
05096               }
05097             }
05098             break ;
05099 
05100             
05101 
05102             case Button2:{
05103 
05104               
05105 
05106               if( seq->button2_enabled && w == seq->wimage )
05107                  ISQ_button2_EV( w , client_data , ev , continue_to_dispatch ) ;
05108               else
05109                  { XBell(seq->dc->display,100); busy=0; EXRETURN; }
05110             }
05111             break ;
05112 
05113             default: break ;
05114          }
05115       }
05116       ISQ_but_done_reset( seq ) ;
05117       break ;
05118 
05119       
05120 
05121       case ConfigureNotify:{
05122          XConfigureEvent * event = (XConfigureEvent *) ev ;
05123 
05124          static int am_active = 0  ;  
05125 
05126 #if 0
05127          
05128          
05129 
05130          { Window rW,cW ; int rx,ry,x,y ; unsigned int mask ;
05131            XQueryPointer(XtDisplay(w),XtWindow(w),&rW,&cW,&rx,&ry,&x,&y,&mask) ;
05132            if( mask & (Button1Mask|Button2Mask|Button3Mask) ) break ;
05133          }
05134 #endif
05135 
05136          if( am_active ) break ;      
05137          am_active = 1 ;
05138 
05139  if(PRINT_TRACING){
05140   char str[256] ;
05141   sprintf(str," .. ConfigureNotify: width=%d height=%d",
05142           event->width,event->height);
05143   STATUS(str) ;
05144  }
05145 
05146          
05147 
05148 
05149          if( w == seq->wimage ){
05150 
05151             if( (seq->sized_xim == NULL)                  ||
05152                 (event->width  != seq->sized_xim->width ) ||
05153                 (event->height != seq->sized_xim->height)   ){
05154 
05155                seq->wimage_width = seq->wimage_height = -1 ; 
05156 
05157                KILL_2ndXIM( seq->given_xim , seq->sized_xim ) ;
05158 
05159                
05160                
05161 
05162 #if 0
05163 fprintf(stderr,"ConfigureNotify: width=%d height=%d\n",event->width,event->height);
05164 #endif
05165 
05166                if( AFNI_yesenv("AFNI_ENFORCE_ASPECT") && !seq->opt.free_aspect ){
05167                  static int last_time=0 ; int now_time=NI_clock_time() ;
05168                  if( now_time == 0 || now_time-last_time > 33 )
05169                    ISQ_reset_dimen( seq, seq->last_width_mm, seq->last_height_mm ) ;
05170 #if 0
05171 else fprintf(stderr,"  -- too soon to enforce aspect!\n") ;
05172 #endif
05173                  last_time = now_time ;
05174                }
05175 
05176                
05177 
05178                ISQ_show_image( seq ) ;
05179             }
05180 
05181          } else if( w == seq->wbar ){
05182 
05183              if( (seq->sized_xbar == NULL)                  ||
05184                  (event->width  != seq->sized_xbar->width ) ||
05185                  (event->height != seq->sized_xbar->height)   ){
05186 
05187                KILL_2ndXIM( seq->given_xbar , seq->sized_xbar ) ;
05188                ISQ_show_bar( seq ) ;
05189             }
05190          }
05191 
05192          am_active = 0 ;
05193       }
05194       break ;
05195 
05196       
05197 
05198       default: break ;
05199 
05200    } 
05201 
05202    busy=0; EXRETURN ;
05203 }
05204 
05205 
05206 
05207 
05208 
05209 #define NPTS_MAX 4095  
05210 
05211 void ISQ_button2_EV( Widget w , XtPointer client_data ,
05212                      XEvent * ev , Boolean * continue_to_dispatch )
05213 {
05214    MCW_imseq * seq = (MCW_imseq *) client_data ;
05215    ISQ_cbs cbs ;
05216    static int nsav ;
05217    static int * bxsav=NULL , *bysav=NULL , *xyout=NULL ;
05218 
05219 ENTRY("ISQ_button2_EV") ;
05220 
05221    
05222 
05223    if( !ISQ_REALZ(seq) || !seq->button2_enabled || w != seq->wimage ) EXRETURN ;
05224 
05225    ISQ_timer_stop(seq) ;
05226 
05227    switch( ev->type ){
05228 
05229       
05230 
05231       case ButtonPress:{
05232          XButtonEvent * event = (XButtonEvent *) ev ;
05233          int bx,by , but , xim,yim,zim ;
05234 
05235          but = event->button ; if( but != Button2 ) EXRETURN ;
05236 
05237          seq->button2_active = 1 ;  
05238 
05239          
05240 
05241          if( bxsav == NULL ){
05242             bxsav = (int *) malloc( sizeof(int) * (NPTS_MAX+1) ) ;
05243             bysav = (int *) malloc( sizeof(int) * (NPTS_MAX+1) ) ;
05244          }
05245 
05246          
05247 
05248          bx = event->x ; by = event->y ;
05249          bxsav[0] = bx ; bysav[0] = by ; nsav = 1 ;
05250 
05251          
05252 
05253 
05254          seq->wimage_width = -1 ;
05255          ISQ_mapxy( seq , bx,by , &xim,&yim,&zim ) ;
05256          if( xim < 0 || yim < 0 || zim < 0 || zim >= seq->status->num_total ){
05257             seq->button2_active = 0 ;         
05258             XBell( seq->dc->display , 100 ) ; 
05259             EXRETURN ;
05260          }
05261 
05262          
05263 
05264          if( seq->button2_drawmode != BUTTON2_NODRAW ){
05265             DC_fg_colorpix( seq->dc , seq->button2_pixel ) ;
05266             XDrawPoint( seq->dc->display , XtWindow(seq->wimage) ,
05267                         seq->dc->myGC , bx,by ) ;
05268          }
05269       }
05270       break ;
05271 
05272       
05273 
05274       case ButtonRelease:{
05275          XButtonEvent * event = (XButtonEvent *) ev ;
05276          int bx,by ;
05277          int ii,nout , nim , xim,yim,zim ;
05278 
05279          
05280 
05281          if( !seq->button2_active || event->button != Button2 ) EXRETURN ;
05282 
05283          bx = event->x ; by = event->y ;  
05284 
05285          
05286 
05287          if( bx != bxsav[nsav-1] || by != bysav[nsav-1] ){
05288 
05289             if( seq->button2_drawmode == BUTTON2_POINTS ){
05290                XDrawPoint( seq->dc->display , XtWindow(seq->wimage) ,
05291                            seq->dc->myGC , bx,by ) ;
05292             } else if( seq->button2_drawmode != BUTTON2_NODRAW ){
05293                if( seq->button2_width > 0 )                     
05294                  DC_linewidth( seq->dc , seq->button2_width ) ;
05295                XDrawLine( seq->dc->display , XtWindow(seq->wimage) ,
05296                           seq->dc->myGC , bxsav[nsav-1],bysav[nsav-1],bx,by ) ;
05297                if( seq->button2_width > 0 ) DC_linewidth( seq->dc , 0 ) ;
05298             }
05299 
05300             bxsav[nsav] = bx ; bysav[nsav] = by ;
05301             if( nsav < NPTS_MAX ) nsav++ ;
05302          }
05303 
05304          
05305 
05306 
05307          if( seq->button2_drawmode == BUTTON2_CLOSEDPOLY && nsav > 2 ){
05308             if( seq->button2_width > 0 )                     
05309               DC_linewidth( seq->dc , seq->button2_width ) ;
05310             XDrawLine( seq->dc->display , XtWindow(seq->wimage) ,
05311                        seq->dc->myGC , bxsav[nsav-1],bysav[nsav-1] ,
05312                                        bxsav[0]     ,bysav[0]       ) ;
05313             if( seq->button2_width > 0 ) DC_linewidth( seq->dc , 0 ) ;
05314 
05315             
05316 
05317             bxsav[nsav] = bxsav[0] ; bysav[nsav] = bysav[0] ;
05318             if( nsav < NPTS_MAX ) nsav++ ;
05319          }
05320 
05321          
05322 
05323          if( xyout == NULL )
05324             xyout = (int *) malloc( sizeof(int) * 2*NPTS_MAX ) ;
05325 
05326          
05327 
05328 
05329 
05330          seq->wimage_width = -1 ;
05331          ISQ_mapxy( seq , bxsav[0] , bysav[0] , &xim,&yim,&zim ) ;
05332          nim = zim ; xyout[0] = xim ; xyout[1] = yim ; nout = 1 ;
05333          for( ii=1 ; ii < nsav ; ii++ ){
05334             ISQ_mapxy( seq , bxsav[ii] , bysav[ii] , &xim,&yim,&zim ) ;
05335             if( zim == nim && xim >= 0 && yim >= 0 ){
05336                xyout[2*nout] = xim ; xyout[2*nout+1] = yim ;
05337                nout++ ;
05338             }
05339          }
05340 
05341          
05342 
05343          cbs.reason   = isqCR_button2_points ;
05344          cbs.event    = ev ;
05345          cbs.key      = ii ;                 
05346          cbs.nim      = nim ;                
05347          cbs.userdata = (XtPointer) xyout ;  
05348 #if 0
05349          seq->status->send_CB( seq , seq->getaux , &cbs ) ;
05350 #else
05351          SEND(seq,cbs) ;
05352 #endif
05353 
05354          seq->button2_active = 0 ;  
05355       }
05356       break ;
05357 
05358       
05359 
05360 
05361       case MotionNotify:{
05362          XMotionEvent * event = (XMotionEvent *) ev ;
05363          int bx,by ;
05364 
05365          
05366 
05367          if( !seq->button2_active || (event->state & Button2Mask) == 0 ) EXRETURN ;
05368 
05369          
05370 
05371          bx = event->x ; by = event->y ;
05372          if( bx == bxsav[nsav-1] && by == bysav[nsav-1] ) EXRETURN ;
05373 
05374          
05375 
05376          if( seq->button2_drawmode == BUTTON2_POINTS ){
05377             XDrawPoint( seq->dc->display , XtWindow(seq->wimage) ,
05378                         seq->dc->myGC , bx,by ) ;
05379          } else if( seq->button2_drawmode != BUTTON2_NODRAW ){
05380             if( seq->button2_width > 0 )                     
05381               DC_linewidth( seq->dc , seq->button2_width ) ;
05382             XDrawLine( seq->dc->display , XtWindow(seq->wimage) ,
05383                        seq->dc->myGC , bxsav[nsav-1],bysav[nsav-1],bx,by ) ;
05384             if( seq->button2_width > 0 ) DC_linewidth( seq->dc , 0 ) ;
05385          }
05386 
05387          
05388 
05389          bxsav[nsav] = bx ; bysav[nsav] = by ;
05390          if( nsav < NPTS_MAX ) nsav++ ;
05391       }
05392       break ;
05393 
05394    }
05395    EXRETURN ;
05396 }
05397 
05398 
05399 
05400 
05401 
05402 
05403 
05404 void ISQ_but_disp_CB( Widget w, XtPointer client_data, XtPointer call_data )
05405 {
05406    MCW_imseq *seq = (MCW_imseq *) client_data ;
05407    int ib ;
05408    Widget rctop , rcboxes , shtop ;
05409    Widget swtop=NULL ;
05410 
05411 ENTRY("ISQ_but_disp_CB") ;
05412 
05413    if( ! ISQ_REALZ(seq) || seq->dialog != NULL ) EXRETURN ;
05414 
05415    for( ib=0 ; ib < NBUTTON_BOT-1 ; ib++ )        
05416       if( ISQ_but_bot_dial[ib] == True )          
05417         SENSITIZE( seq->wbut_bot[ib] , False ) ;  
05418 
05419    seq->dialog = XtVaCreatePopupShell(
05420                     "menu" , xmDialogShellWidgetClass , seq->wtop ,
05421                        XmNtitle , "Display Options" ,
05422                        XmNdeleteResponse , XmDO_NOTHING ,
05423                        XmNinitialResourcesPersistent , False ,
05424                     NULL ) ;
05425 
05426    SAVEUNDERIZE(seq->dialog) ; 
05427 
05428    DC_yokify( seq->dialog , seq->dc ) ;  
05429 
05430    seq->dialog_starter = NBUT_DISP ;
05431 
05432 #if 1
05433    if( MCW_isitmwm(w) )
05434       XtVaSetValues( seq->dialog ,
05435                        XmNmwmDecorations , MWM_DECOR_BORDER ,
05436                        XmNmwmFunctions ,   MWM_FUNC_MOVE
05437                                          | MWM_FUNC_CLOSE ,
05438                      NULL ) ;
05439 #endif
05440 
05441    XmAddWMProtocolCallback(           
05442            seq->dialog ,
05443            XmInternAtom( seq->dc->display , "WM_DELETE_WINDOW" , False ) ,
05444            ISQ_disp_act_CB , seq ) ;
05445 
05446    for( ib=0 ; ib < NACT_DISP ; ib++ )
05447       ISQ_disp_act[ib].data = (XtPointer) seq ;
05448 
05449    if( seq->dc->height < 1024 ||               
05450        AFNI_yesenv("AFNI_DISP_SCROLLBARS") ){  
05451 
05452       shtop = swtop = XtVaCreateManagedWidget(
05453                  "menu" , xmScrolledWindowWidgetClass , seq->dialog ,
05454                     XmNscrollingPolicy        , XmAUTOMATIC ,
05455                     XmNvisualPolicy           , XmVARIABLE ,
05456                     XmNscrollBarDisplayPolicy , XmSTATIC ,
05457                     XmNinitialResourcesPersistent , False ,
05458                  NULL ) ;
05459    } else {
05460       shtop = seq->dialog ;
05461    }
05462 
05463    rctop = XtVaCreateWidget(
05464               "menu" , xmRowColumnWidgetClass , shtop ,
05465                  XmNpacking    , XmPACK_TIGHT ,
05466                  XmNnumColumns , 1 ,
05467 
05468                  XmNinitialResourcesPersistent , False ,
05469               NULL ) ;
05470 
05471    rcboxes = XtVaCreateWidget(
05472                 "menu" , xmRowColumnWidgetClass , rctop ,
05473                    XmNpacking    , XmPACK_TIGHT ,
05474                    XmNnumColumns , 2 ,
05475 
05476                    XmNinitialResourcesPersistent , False ,
05477               NULL ) ;
05478 
05479    for( ib=0 ; ib < NBOX_DISP ; ib++ ){
05480       int jh ;
05481       char ** bbh = ISQ_bb_allhelp[ib] ;
05482       char ** cch = ISQ_bb_allhint[ib] ;
05483 
05484       
05485 
05486       if( ib == NTOG_IMP ){
05487          int nav = 0 ;
05488 
05489          
05490 
05491          char *save_one_label[] = { "Save One" }  ; 
05492          char *save_agif_label  = "Save Anim GIF" ; 
05493          char *save_mpeg_label  = "Save Anim MPG" ; 
05494          char *save_anim_label[2] ;
05495 
05496          seq->save_one_bbox = new_MCW_bbox( rcboxes ,
05497                                             1 ,
05498                                             save_one_label ,
05499                                             MCW_BB_check ,
05500                                             MCW_BB_frame ,
05501                                             ISQ_disp_act_CB , (XtPointer) seq ) ;
05502          MCW_reghelp_children( seq->save_one_bbox->wrowcol ,
05503                                " \n"
05504                                "When pressed IN, then the 'Save' button\n"
05505                                "will only save a snapshot of the current\n"
05506                                "display.  This is the ONLY way to save\n"
05507                                "a montage.\n"
05508                                "\n"
05509                                "When pressed OUT, then the 'Save' button\n"
05510                                "asks for the first and last image indexes\n"
05511                                "to save, and then saves each individual\n"
05512                                "image (no montage) to a file.\n"
05513                              ) ;
05514          MCW_reghint_children( seq->save_one_bbox->wrowcol ,
05515                                "Save just 1 (including montage)" ) ;
05516 
05517          if( ppmto_agif_filter != NULL || ppmto_mpeg_filter != NULL ){
05518            int nb = 0 ;
05519            if( ppmto_agif_filter != NULL ) save_anim_label[nb++]=save_agif_label;
05520            if( ppmto_mpeg_filter != NULL ) save_anim_label[nb++]=save_mpeg_label;
05521            seq->save_agif_bbox = new_MCW_bbox( rcboxes ,
05522                                                nb ,
05523                                                save_anim_label ,
05524                                                MCW_BB_radio_zero ,
05525                                                MCW_BB_frame ,
05526                                                ISQ_disp_act_CB, (XtPointer)seq );
05527            MCW_reghelp_children( seq->save_agif_bbox->wrowcol ,
05528                                  " \n"
05529                                  "Controls if image sequence is saved to\n"
05530                                  "an animation file, rather than a bunch\n"
05531                                  "of separate image files.\n"
05532                                  "* This takes precedence over 'Save One',\n"
05533                                  "    if it is also turned on.\n"
05534                                  "* GIF animations require gifsicle.\n"
05535                                  "* MPEG-1 animations require mpeg_encode.\n"
05536                                ) ;
05537            MCW_reghint_children( seq->save_agif_bbox->wrowcol ,
05538                                  "Save image sequence to animation" ) ;
05539          } else {
05540            seq->save_agif_bbox = NULL ;
05541          }
05542 
05543          
05544 
05545          if( seq->status->slice_proj != NULL &&
05546              seq->status->slice_proj->num > 0  ){  
05547 
05548              (void) XtVaCreateManagedWidget(
05549                       "menu" , xmSeparatorWidgetClass , rcboxes ,
05550                          XmNseparatorType , XmSINGLE_LINE ,
05551                          XmNinitialResourcesPersistent , False ,
05552                       NULL ) ;
05553 
05554              seq->slice_proj_av =
05555                 new_MCW_optmenu( rcboxes , "Project" ,
05556                                  0 , seq->status->slice_proj->num ,
05557                                  seq->slice_proj_index , 0 ,
05558                                  ISQ_slice_proj_CB , (XtPointer) seq ,
05559                                  ISQ_transform_label ,
05560                                  (XtPointer) seq->status->slice_proj ) ;
05561 
05562              if( seq->status->slice_proj->num >= COLSIZE )
05563                 AVOPT_columnize( seq->slice_proj_av ,
05564                                  (seq->status->slice_proj->num/COLSIZE)+1 ) ;
05565 
05566              MCW_reghelp_children( seq->slice_proj_av->wrowcol ,
05567                                    "Choose a projection function\n"
05568                                    "to apply to plus-or-minus\n"
05569                                    "'Slab' images from each pixel.\n"
05570                                    "Built-in projections:\n"
05571                                    " Minimum = smallest value in slab\n"
05572                                    " Maximum = largest value in slab\n"
05573                                    " Mean    = average value in slab\n"
05574                                    " Median  = median value in slab\n"
05575                                    " Extreme = value farthest from median" ) ;
05576 
05577              MCW_reghint_children( seq->slice_proj_av->wrowcol ,
05578                                    "Image projection function"  ) ;
05579 
05580              seq->slice_proj_range_av =
05581                 new_MCW_optmenu( rcboxes , "Slab +-" ,
05582                                  0 , 19 , seq->slice_proj_range , 0 ,
05583                                  ISQ_slice_proj_CB , (XtPointer) seq ,
05584                                  NULL , NULL ) ;
05585              MCW_reghelp_children( seq->slice_proj_range_av->wrowcol ,
05586                                    "Choose thickness of Project slice\n"
05587                                    "package (in each direction from\n"
05588                                    "central slice).  For example:\n"
05589                                    " 2 ==> slab is 5 images thick\n"
05590                                    "       (2 before, 2 after, central)" ) ;
05591              MCW_reghint_children( seq->slice_proj_range_av->wrowcol ,
05592                                    "Slab half-thickness"              ) ;
05593              nav++ ;
05594          }
05595 
05596          
05597 
05598          if( seq->status->transforms0D != NULL &&
05599              seq->status->transforms0D->num > 0  ){
05600 
05601              (void) XtVaCreateManagedWidget(
05602                       "menu" , xmSeparatorWidgetClass , rcboxes ,
05603                          XmNseparatorType , XmSINGLE_LINE ,
05604                          XmNinitialResourcesPersistent , False ,
05605                       NULL ) ;
05606 
05607              seq->transform0D_av =
05608                 new_MCW_optmenu( rcboxes , "Tran 0D" ,
05609                                  0 , seq->status->transforms0D->num ,
05610                                  seq->transform0D_index , 0 ,
05611                                  ISQ_transform_CB , (XtPointer) seq ,
05612                                  ISQ_transform_label ,
05613                                  (XtPointer) seq->status->transforms0D ) ;
05614 
05615              if( seq->status->transforms0D->num >= COLSIZE )
05616                 AVOPT_columnize( seq->transform0D_av ,
05617                                  (seq->status->transforms0D->num/COLSIZE)+1 ) ;
05618 
05619              MCW_reghelp_children( seq->transform0D_av->wrowcol ,
05620                                    "Choose a function to apply to\n"
05621                                    "each point in the image." ) ;
05622              MCW_reghint_children( seq->transform0D_av->wrowcol ,
05623                                    "Pointwise transformations" ) ;
05624              nav++ ;
05625          }
05626 
05627          
05628 
05629          if( seq->status->transforms2D != NULL &&
05630              seq->status->transforms2D->num > 0  ){
05631 
05632              (void) XtVaCreateManagedWidget(
05633                       "menu" , xmSeparatorWidgetClass , rcboxes ,
05634                          XmNseparatorType , XmSINGLE_LINE ,
05635                          XmNinitialResourcesPersistent , False ,
05636                       NULL ) ;
05637 
05638              seq->transform2D_av =
05639                 new_MCW_optmenu( rcboxes , "Tran 2D" ,
05640                                  0 , seq->status->transforms2D->num ,
05641                                  seq->transform2D_index , 0 ,
05642                                  ISQ_transform_CB , (XtPointer) seq ,
05643                                  ISQ_transform_label ,
05644                                  (XtPointer) seq->status->transforms2D ) ;
05645 
05646              if( seq->status->transforms2D->num >= COLSIZE )
05647                 AVOPT_columnize( seq->transform2D_av ,
05648                                  (seq->status->transforms2D->num/COLSIZE)+1 ) ;
05649 
05650              MCW_reghelp_children( seq->transform2D_av->wrowcol ,
05651                                    "Choose a function to apply to\n"
05652                                    "the underlay image as a whole." ) ;
05653              MCW_reghint_children( seq->transform2D_av->wrowcol ,
05654                                    "Global transformations" ) ;
05655              nav++ ;
05656          }
05657 
05658          
05659 
05660          if( nav > 0 && seq->status->send_CB != NULL ){
05661             (void) XtVaCreateManagedWidget(
05662                      "menu" , xmSeparatorWidgetClass , rcboxes ,
05663                         XmNseparatorType , XmSINGLE_LINE ,
05664                         XmNinitialResourcesPersistent , False ,
05665                      NULL ) ;
05666 
05667             seq->rowgraph_av =
05668                new_MCW_optmenu( rcboxes , "RowGraphs" ,
05669                                 0 , ROWGRAPH_MAX , seq->rowgraph_num , 0 ,
05670                                 ISQ_rowgraph_CB , (XtPointer) seq ,
05671                                 ISQ_rowgraph_label , NULL ) ;
05672             AVOPT_columnize( seq->rowgraph_av , 2 ) ;
05673 
05674             MCW_reghelp_children( seq->rowgraph_av->wrowcol ,
05675                                   "Rowgraphs are plots of the underlay\n"
05676                                   "(grayscale) image intensity as\n"
05677                                   "x vs. y graphs.  Each graph is from\n"
05678                                   "one displayed horizontal row of the\n"
05679                                   "image.  The bottom rowgraph is from\n"
05680                                   "the image row under the crosshairs.\n"
05681                                   "Upper rowgraphs are from higher image\n"
05682                                   "rows.  Note that image transformations\n"
05683                                   "functions and image rotations/flips\n"
05684                                   "will affect the rowgraphs as well as\n"
05685                                   "the image display.\n\n"
05686                                   "N.B.: The color 'UK Flag' marker indicates\n"
05687                                   "      the crosshair focus point. It can be\n"
05688                                   "      turned off via the 'No Overlay' button."
05689                                  ) ;
05690             MCW_reghint_children( seq->rowgraph_av->wrowcol ,
05691                                   "Number of image rows to graph" ) ;
05692             nav++ ;
05693          }
05694 
05695          
05696 
05697          if( nav > 0 && seq->status->send_CB != NULL ){
05698             (void) XtVaCreateManagedWidget(
05699                      "menu" , xmSeparatorWidgetClass , rcboxes ,
05700                         XmNseparatorType , XmSINGLE_LINE ,
05701                         XmNinitialResourcesPersistent , False ,
05702                      NULL ) ;
05703 
05704             seq->surfgraph_av =
05705                new_MCW_optmenu( rcboxes , "SurfGraph" ,
05706                                 0 , SURFGRAPH_MAX , seq->surfgraph_num , 0 ,
05707                                 ISQ_surfgraph_CB , (XtPointer) seq ,
05708                                 ISQ_surfgraph_label , NULL ) ;
05709 
05710             MCW_reghelp_children( seq->surfgraph_av->wrowcol ,
05711                                   "The SurfGraph is a wiremesh plot of the\n"
05712                                   "underlay (grayscale) image intensity vs.\n"
05713                                   "x and y.  Use the arrows in the SurfGraph\n"
05714                                   "window to rotate the viewpoint; use the\n"
05715                                   "middle button between the arrows to reset\n"
05716                                   "the viewpoint to the default orientation.\n"
05717                                   "\n"
05718                                   "N.B.: The plotting routine may produce some\n"
05719                                   "        erroneous vertical lines on occasion.\n"
05720                                   "      The color 'UK Flag' marker indicates\n"
05721                                   "        crosshair focus point.  It is drawn\n"
05722                                   "        on top of the surface at the end, and\n"
05723                                   "        so is always visible, even if it should\n"
05724                                   "        be hidden behind the surface; that is,\n"
05725                                   "        it shines through, no matter what.\n"
05726                                   "      The color marker can be turned off with\n"
05727                                   "        the 'No Overlay' button."
05728                                  ) ;
05729             MCW_reghint_children( seq->surfgraph_av->wrowcol ,
05730                                   "Plot wiremesh surface?" ) ;
05731             nav++ ;
05732          }
05733 
05734          
05735 
05736          if( nav ) (void) XtVaCreateManagedWidget(
05737                             "menu" , xmSeparatorWidgetClass , rcboxes ,
05738                                XmNseparatorType , XmSINGLE_LINE ,
05739                                XmNinitialResourcesPersistent , False ,
05740                             NULL ) ;
05741       }
05742 
05743       
05744 
05745       seq->bbox[ib] = new_MCW_bbox( rcboxes ,
05746                                      ISQ_dispbb[ib].nbut ,
05747                                      ISQ_dispbb[ib].lbut ,
05748                                      ISQ_dispbb[ib].type ,
05749                                      ISQ_dispbb[ib].frame ,
05750                                      ISQ_disp_act_CB , (XtPointer) seq ) ;
05751 
05752       seq->bbox[ib]->parent = (XtPointer) seq ;
05753 
05754       seq->num_bbox ++ ;
05755 
05756       for( jh=0 ; jh < seq->bbox[ib]->nbut ; jh++ ){
05757          MCW_register_help( seq->bbox[ib]->wbut[jh] , bbh[jh] ) ;
05758          MCW_register_hint( seq->bbox[ib]->wbut[jh] , cch[jh] ) ;
05759       }
05760 
05761    }
05762 
05763 #define NO_GROUP_SCALE
05764 #ifdef  NO_GROUP_SCALE
05765    XtUnmanageChild( seq->bbox[NTOG_SCL]->wtop ) ;  
05766 #endif
05767 
05768    if( seq->last_image_type != MRI_complex )
05769       XtUnmanageChild( seq->bbox[NTOG_CX]->wtop ) ;
05770 
05771    XtManageChild( rcboxes ) ;
05772 
05773    (void) MCW_action_area( rctop , ISQ_disp_act , NACT_DISP ) ;
05774 
05775    XtManageChild( rctop ) ;
05776 
05777    if( swtop != NULL ){       
05778      int wx,hy , cmax ;
05779      MCW_widget_geom( rctop  , &wx,&hy,NULL,NULL ) ;
05780 
05781      cmax = HeightOfScreen(XtScreen(rctop)) - 128 ;
05782      if( hy > cmax ) hy = cmax ;
05783 
05784      XtVaSetValues( seq->dialog , XmNwidth,wx+29,XmNheight,hy+19 , NULL ) ;
05785    }
05786 
05787    ISQ_place_dialog( seq ) ;  
05788 
05789    XtPopup( seq->dialog , XtGrabNone ) ;
05790 
05791    ISQ_disp_options( seq , False ) ;  
05792    seq->save_opt = seq->opt ;         
05793 
05794    NORMAL_cursorize( seq->dialog ) ;
05795 
05796    ISQ_but_done_reset( seq ) ;
05797    EXRETURN ;
05798 }
05799 
05800 
05801 
05802 
05803 
05804 void ISQ_place_dialog( MCW_imseq *seq )
05805 {
05806    if( ISQ_REALZ(seq) && !seq->dont_place_dialog )
05807      ISQ_place_widget( seq->wtop , seq->dialog ) ;
05808 
05809    return ;
05810 }
05811 
05812 
05813 
05814 void ISQ_place_widget( Widget wmain , Widget w )  
05815 {
05816    int dw,dh,dx,dy , xp,yp , wx,hy,xx,yy , sh,sw ;
05817 
05818 ENTRY("ISQ_place_widget") ;
05819 
05820    if( wmain == (Widget)NULL || w == (Widget)NULL ) EXRETURN ;
05821    if( !XtIsRealized(wmain)  || !XtIsRealized(w)  ) EXRETURN ;
05822 
05823    MCW_widget_geom( wmain , &wx,&hy,&xx,&yy ) ;  
05824    MCW_widget_geom( w     , &dw,&dh,&dx,&dy ) ;  
05825 
05826    sh = HeightOfScreen(XtScreen(wmain)) ;
05827    sh = WidthOfScreen (XtScreen(wmain)) ;
05828 
05829    xp = xx+wx+8 ;
05830    if( xp+dw > sw ) xp = xx-dw-8 ;
05831    if( xp    < 0  ) xp = 0 ;
05832 
05833    yp = yy-4 ;
05834    if( yp+dh > sh ) yp = sh - dh ;
05835    if( yp    < 0  ) yp = 0 ;
05836 
05837    RWC_xineramize( XtDisplay(wmain) , xp,yp,dw,dh , &xp,&yp ); 
05838 
05839    XtVaSetValues( w , XmNx , xp , XmNy , yp , NULL ) ;
05840    EXRETURN ;
05841 }
05842 
05843 
05844 
05845 
05846 
05847 void ISQ_disp_act_CB( Widget w, XtPointer client_data, XtPointer call_data )
05848 {
05849    MCW_imseq * seq           = (MCW_imseq *) client_data ;
05850    XmAnyCallbackStruct * cbs = (XmAnyCallbackStruct *) call_data ;
05851 
05852    int ib , close_window ;
05853    char * wname ;
05854    Boolean new_opt = False ;
05855 
05856 #ifdef FLASH_TOGGLE
05857    Boolean flasher ;
05858 #endif
05859 
05860 ENTRY("ISQ_disp_act_CB") ;
05861 
05862    if( !ISQ_REALZ(seq) || seq->dialog==NULL || seq->dialog_starter!=NBUT_DISP ) EXRETURN ;
05863 
05864    wname = XtName(w) ;
05865 
05866    for( ib=0 ; ib < NACT_DISP ; ib++ )           
05867       if( strcmp(wname,ISQ_disp_act[ib].label) == 0 ) break ;
05868 
05869    close_window = (ib == DISP_OK)  
05870                  ||
05871                   ( cbs->reason != XmCR_ACTIVATE       &&   
05872                     cbs->reason != XmCR_DISARM           ); 
05873 
05874 #ifdef FLASH_TOGGLE
05875    flasher = (cbs->reason == XmCR_DISARM) && (!close_window) ;
05876    if( flasher ) MCW_invert_widget( w ) ;
05877 #endif
05878 
05879    if( ib == DISP_UNDO ){               
05880       seq->opt = seq->save_opt ;        
05881       ISQ_disp_options( seq , False ) ;
05882       new_opt = True ;
05883       AV_SENSITIZE(seq->ov_opacity_av,!seq->opt.no_overlay) ; 
05884 
05885    } else {                                     
05886       new_opt = ISQ_disp_options( seq , True ); 
05887    }
05888 
05889    if( close_window ){                          
05890       XtDestroyWidget( seq->dialog ) ;
05891       seq->dialog = NULL ;
05892       for( ib=0 ; ib < NBUTTON_BOT-1 ; ib++ )       
05893          if( ISQ_but_bot_dial[ib] == True )         
05894             SENSITIZE( seq->wbut_bot[ib] , True ) ; 
05895 
05896       for( ib=0 ; ib < seq->num_bbox ; ib++ ) myXtFree( seq->bbox[ib] ) ;
05897       seq->num_bbox = 0 ;
05898       seq->dialog_starter = -1 ;
05899 
05900       FREE_AV( seq->transform0D_av ) ;
05901       FREE_AV( seq->transform2D_av ) ;
05902       FREE_AV( seq->rowgraph_av )    ;
05903       FREE_AV( seq->surfgraph_av )   ;  
05904    }
05905 
05906    if( new_opt ){
05907       ISQ_redisplay( seq , -1 , isqDR_reimage ) ;  
05908 
05909       
05910 
05911       if( ISQ_USE_SIDES(seq) ){
05912          seq->im_label[0] = '\0' ;  
05913          ISQ_draw_winfo( seq ) ;
05914       }
05915    }
05916 
05917 #ifdef FLASH_TOGGLE
05918    if( flasher ) MCW_invert_widget( w ) ;  
05919 #endif
05920 
05921    ISQ_but_done_reset( seq ) ;
05922    EXRETURN ;
05923 }
05924 
05925 
05926 
05927 
05928 
05929 
05930 
05931 
05932 
05933 Boolean ISQ_disp_options( MCW_imseq * seq , Boolean set )
05934 {
05935    int bval[NBOX_DISP] ;
05936    int ib ;
05937 
05938 ENTRY("ISQ_disp_options") ;
05939 
05940    if( !ISQ_VALID(seq) || seq->dialog==NULL || seq->dialog_starter!=NBUT_DISP )
05941       RETURN(False) ;
05942 
05943    if( set ){
05944       ISQ_options inopt = seq->opt ;
05945       Boolean changed ;
05946 
05947       for( ib=0 ; ib < NBOX_DISP ; ib++ )
05948          bval[ib] = MCW_val_bbox( seq->bbox[ib] ) ;
05949 
05950       seq->opt.mirror      = ( bval[NTOG_MIR] & 1 ) != 0 ;
05951 
05952       seq->opt.rot         = bval[NTOG_ROT] ;
05953 
05954       seq->opt.no_overlay  = ( bval[NTOG_COL] & 1 ) != 0 ;
05955 
05956       AV_SENSITIZE(seq->ov_opacity_av,!seq->opt.no_overlay) ; 
05957 
05958       seq->opt.scale_group = bval[NTOG_SCL] ;
05959 
05960       seq->opt.scale_range = bval[NTOG_RNG] ;
05961 
05962       seq->opt.free_aspect = ( bval[NTOG_ASP] & ISQ_ASPECT    ) != 0 ;
05963       seq->opt.save_nsize  = ( bval[NTOG_SAV] & ISQ_SAV_NSIZE ) != 0 ;
05964       seq->opt.save_pnm    = ( bval[NTOG_SAV] & ISQ_SAV_PNM   ) != 0 ;
05965 
05966       seq->opt.save_one    = MCW_val_bbox(seq->save_one_bbox)   != 0 ; 
05967 
05968       seq->opt.save_agif = seq->opt.save_mpeg = 0 ;
05969       if( seq->save_agif_bbox != NULL ){
05970          int bv = MCW_val_bbox(seq->save_agif_bbox) ;
05971                                                         
05972          switch( bv ){        
05973            case 1:
05974                   if( ppmto_agif_filter != NULL ) seq->opt.save_agif = 1 ;
05975              else if( ppmto_mpeg_filter != NULL ) seq->opt.save_mpeg = 1 ;
05976            break ;
05977 
05978            case 2:
05979                   if( ppmto_mpeg_filter != NULL ) seq->opt.save_mpeg = 1 ;
05980            break ;
05981          }
05982       }
05983 
05984       seq->opt.save_filter = -1 ;
05985       if( bval[NTOG_SAV] > ISQ_SAV_PNM && ppmto_num > 0 ){  
05986          int ii ;
05987          for( ii=0 ; ii < ppmto_num ; ii++ ){
05988             if( bval[NTOG_SAV] == ppmto_bval[ii] ){
05989                seq->opt.save_filter = ii ; break ;
05990             }
05991          }
05992       }
05993 
05994       SET_SAVE_LABEL(seq) ;
05995 
05996       seq->opt.improc_code = bval[NTOG_IMP] ;
05997 
05998       seq->opt.cx_code = bval[NTOG_CX] ;
05999 
06000       
06001 
06002       if( seq->opt.rot != ISQ_ROT_0   &&
06003           seq->opt.rot != ISQ_ROT_90  &&
06004           seq->opt.rot != ISQ_ROT_180 &&
06005           seq->opt.rot != ISQ_ROT_270   ) seq->opt.rot = inopt.rot ;
06006 
06007       if( seq->opt.scale_group != ISQ_SCL_AUTO &&
06008           seq->opt.scale_group != ISQ_SCL_GRP )
06009                                seq->opt.scale_group = inopt.scale_group ;
06010 
06011       if( seq->opt.scale_range != ISQ_RNG_MINTOMAX &&
06012           seq->opt.scale_range != ISQ_RNG_02TO98 )
06013                                seq->opt.scale_range = inopt.scale_range ;
06014 
06015       changed = ! ISQ_OPT_EQUAL( seq->opt , inopt ) ;
06016 
06017       RETURN(changed) ;
06018 
06019    } else {
06020 
06021       bval[NTOG_MIR] = (seq->opt.mirror) ? 1 : 0 ;
06022       bval[NTOG_ROT] = seq->opt.rot ;
06023 
06024       bval[NTOG_COL] = (seq->opt.no_overlay << 0 ) ;
06025 
06026       bval[NTOG_SCL] = seq->opt.scale_group ;
06027       bval[NTOG_RNG] = seq->opt.scale_range ;
06028 
06029       bval[NTOG_ASP] = (seq->opt.free_aspect) ? ISQ_ASPECT    : 0 ;
06030 
06031       bval[NTOG_SAV] = ( (seq->opt.save_nsize)? ISQ_SAV_NSIZE : 0 )
06032                       +( (seq->opt.save_pnm)  ? ISQ_SAV_PNM   : 0 ) ;
06033 
06034       if( seq->opt.save_filter >= 0 && ppmto_num > 0 )       
06035          bval[NTOG_SAV] = ppmto_bval[seq->opt.save_filter] ;
06036 
06037       bval[NTOG_IMP] = seq->opt.improc_code ;
06038 
06039       bval[NTOG_CX]  = seq->opt.cx_code ;
06040 
06041       for( ib=0 ; ib < NBOX_DISP ; ib++ )
06042          MCW_set_bbox( seq->bbox[ib] , bval[ib] ) ;
06043 
06044       MCW_set_bbox( seq->save_one_bbox ,
06045                     (seq->opt.save_one) ? 1 : 0 ) ; 
06046 
06047       if( seq->save_agif_bbox != NULL ){      
06048          int bv=0 ; 
06049          if( ppmto_agif_filter != NULL )
06050            bv = (seq->opt.save_agif) + (seq->opt.save_mpeg)*2 ;
06051          else if( ppmto_mpeg_filter != NULL )
06052            bv = (seq->opt.save_mpeg) ;
06053          MCW_set_bbox( seq->save_agif_bbox , bv ) ;
06054       }
06055 
06056       RETURN(False) ;
06057    }
06058 }
06059 
06060 
06061 
06062 
06063 
06064 
06065 
06066 
06067 
06068 void ISQ_statify_all( MCW_imseq * seq , Boolean stop_on_minmax )
06069 {
06070    Boolean done ;
06071    Widget wmsg ;
06072 
06073 ENTRY("ISQ_statify_all") ;
06074 
06075    if( ! ISQ_VALID(seq) ) EXRETURN ;
06076 
06077    
06078 
06079    if( !seq->glstat->mm_done ){
06080       wmsg = MCW_popup_message( seq->wtop ,
06081                                 "Please Wait.\nComputing Statistics." ,
06082                                 MCW_CALLER_KILL ) ;
06083    } else {
06084       wmsg = MCW_popup_message( seq->wtop ,
06085                                 "Please Wait.\nComputing Histogram." ,
06086                                 MCW_CALLER_KILL ) ;
06087    }
06088 
06089    XBell( seq->dc->display , 100 ) ;
06090 
06091    WATCH_cursorize( seq->wtop ) ;
06092    WATCH_cursorize( wmsg ) ;
06093    if( seq->dialog != NULL )
06094       WATCH_cursorize( seq->dialog ) ;
06095 
06096    XFlush( seq->dc->display ) ;
06097 
06098    if( seq->glstat->worker != 0 ){  
06099       XtRemoveWorkProc( seq->glstat->worker ) ;
06100       seq->glstat->worker = 0 ;
06101    }
06102 
06103    
06104    do{
06105 
06106       done = ISQ_statistics_WP( (XtPointer) seq ) ;
06107       done = done || ( stop_on_minmax && seq->glstat->mm_done ) ;
06108 
06109    } while ( ! done ) ;
06110    
06111 
06112    XtDestroyWidget( wmsg ) ;
06113 
06114    NORMAL_cursorize( seq->wtop ) ;
06115    if( seq->dialog != NULL )
06116       NORMAL_cursorize( seq->dialog ) ;
06117 
06118    EXRETURN;
06119 }
06120 
06121 
06122 
06123 Boolean ISQ_statistics_WP( XtPointer client_data )
06124 {
06125    MCW_imseq * seq = (MCW_imseq *) client_data ;
06126    ISQ_glob_statistics * gl ;
06127 
06128    MRI_IMAGE * im ;
06129    register int ntot , nser , nn ;
06130 
06131 ENTRY("ISQ_statistics_WP") ;
06132 
06133    if( ! ISQ_VALID(seq) ) RETURN( True );
06134 
06135    gl   = seq->glstat ;
06136    ntot = seq->status->num_total ;  
06137    nser = seq->status->num_series ;
06138 
06139    
06140 
06141    if( ! gl->mm_done ){  
06142 
06143       for( nn=0 ; nn < ntot ; nn++ )
06144          if( ! seq->imstat[nn].one_done ) break ;
06145 
06146       if( nn >= ntot ){ 
06147 
06148          gl->min = seq->imstat[0].min ;
06149          gl->max = seq->imstat[0].max ;
06150          for( nn=1 ; nn < nser ; nn++ ){ 
06151             gl->min = MIN( gl->min , seq->imstat[nn].min ) ;
06152             gl->max = MAX( gl->max , seq->imstat[nn].max ) ;
06153          }
06154          ISQ_SCLEV(gl->min,gl->max,seq->dc->ncol_im,gl->scl_mm,gl->lev_mm);
06155          gl->mm_done = True ;
06156 
06157          RETURN( False );  
06158       }
06159 
06160       
06161 
06162 #if 0
06163       im = (MRI_IMAGE *) seq->getim( nn , isqCR_getimage , seq->getaux ) ;
06164 #else
06165       AFNI_CALL_VALU_3ARG( seq->getim , MRI_IMAGE *,im ,
06166                            int,nn , int,isqCR_getimage , XtPointer,seq->getaux ) ;
06167 #endif
06168       if( im != NULL ){
06169         ISQ_statify_one( seq , nn , im ) ; KILL_1MRI(im) ;
06170       }
06171       RETURN( False );   
06172    }
06173 
06174    
06175    
06176 
06177    if( ! gl->per_done ){  
06178 
06179       for( nn=0 ; nn < nser ; nn++ )
06180          if( ! seq->imstat[nn].glob_done ) break ;
06181 
06182       if( nn >= nser ){ 
06183 
06184          ISQ_perpoints( gl->min,gl->max,gl->hist ,
06185                         &(gl->per02) , &(gl->per98) ) ;
06186 
06187          ISQ_SCLEV( gl->per02 , gl->per98 ,
06188                     seq->dc->ncol_im , gl->scl_per , gl->lev_per ) ;
06189 
06190          gl->per_done = True ;
06191 
06192          RETURN( True );  
06193       }
06194 
06195       
06196 
06197 #if 0
06198       im = (MRI_IMAGE *) seq->getim( nn , isqCR_getimage , seq->getaux ) ;
06199 #else
06200       AFNI_CALL_VALU_3ARG( seq->getim , MRI_IMAGE *,im ,
06201                            int,nn , int,isqCR_getimage , XtPointer,seq->getaux ) ;
06202 #endif
06203       if( im != NULL ){
06204          ISQ_statify_one( seq , nn , im ) ; KILL_1MRI(im) ;
06205       }
06206       RETURN( False );   
06207    }
06208 
06209    
06210 
06211    fprintf(stderr,"\a\n*** imseq work process error!\n") ;
06212    RETURN( True );
06213 }
06214 
06215 
06216 
06217 
06218 
06219 void ISQ_statify_one( MCW_imseq * seq , int n , MRI_IMAGE * im )
06220 {
06221    ISQ_indiv_statistics * st ;
06222    ISQ_glob_statistics *  gl ;
06223    static int hist[NHISTOG] ; 
06224 
06225 ENTRY("ISQ_statify_one") ;
06226 
06227    
06228 
06229    if( ! ISQ_VALID(seq) || n < 0 || n >= seq->status->num_total ) EXRETURN ;
06230 
06231    st = &( seq->imstat[n] ) ;
06232    gl = seq->glstat ;
06233 
06234    if( im->kind == MRI_rgb ) EXRETURN ;  
06235 
06236    if( ! st->one_done ){  
06237 
06238       st->min = mri_min( im ) ;
06239       st->max = mri_max( im ) ;
06240 
06241       ISQ_SCLEV( st->min , st->max ,
06242                  seq->dc->ncol_im , st->scl_mm , st->lev_mm ) ;
06243 
06244       mri_histogram( im , st->min , st->max , True , NHISTOG,hist ) ;
06245 
06246       ISQ_perpoints( st->min,st->max,hist , &(st->per02) , &(st->per98) ) ;
06247 
06248       ISQ_SCLEV( st->per02 , st->per98 ,
06249                  seq->dc->ncol_im , st->scl_per , st->lev_per ) ;
06250 
06251       
06252 
06253       switch( im->kind ){
06254         default:        st->entropy =        mri_entropy8(im) ; break;
06255         case MRI_short:
06256         case MRI_float: st->entropy = 0.5l * mri_entropy16(im); break;
06257       }
06258 
06259       st->one_done = True ;
06260 
06261    } else if( n < seq->status->num_series &&
06262               ! st->glob_done               ){  
06263 
06264       mri_histogram( im , gl->min , gl->max , False , NHISTOG , gl->hist ) ;
06265       st->glob_done = True ;
06266    }
06267 
06268    EXRETURN ;
06269 }
06270 
06271 
06272 
06273 void ISQ_perpoints( float bot , float top ,
06274                     int hist[] , float * per02 , float * per98 )
06275 {
06276    register int ih , nsum , ns02 , ns98 ;
06277    float prev , cur , frac , dbin ;
06278    static int hcum[NHISTOG] ;  
06279 
06280 ENTRY("ISQ_perpoints") ;
06281 
06282    nsum = 0 ;
06283    for( ih=0 ; ih < NHISTOG ; ih++ ) hcum[ih] = nsum += hist[ih] ;
06284 
06285    ns02 = 0.02 * nsum ;  
06286    ns98 = 0.98 * nsum ;
06287    dbin = (top-bot) / NHISTOG ;
06288 
06289    
06290 
06291    for( ih=0 ; ih < NHISTOG ; ih++ ) if( hcum[ih] >= ns02 ) break ;
06292 
06293    if( ih == NHISTOG ) ih-- ;
06294 
06295    prev   = (ih == 0) ? (0.0) : hcum[ih-1] ;
06296    cur    = hcum[ih] ; if( cur <= prev ) cur = 1.01 * prev + 1.0 ;
06297    frac   = ih + (ns02-prev)/(cur-prev) ;
06298    *per02 = bot + dbin * frac ;
06299 
06300    if( *per02 < bot ) *per02 = bot ;
06301 
06302    
06303 
06304    for( ; ih < NHISTOG ; ih++ ) if( hcum[ih] >= ns98 ) break ;
06305 
06306    if( ih == NHISTOG ) ih-- ;
06307 
06308    prev   = (ih == 0) ? (0.0) : hcum[ih-1] ;
06309    cur    = hcum[ih] ; if( cur <= prev ) cur = 1.01 * prev + 1.0 ;
06310    frac   = ih + (ns98-prev)/(cur-prev) ;
06311    *per98 = bot + dbin * frac ;
06312 
06313    if( *per98 > top ) *per98 = top ;
06314 
06315    EXRETURN ;
06316 }
06317 
06318 
06319 
06320 
06321 
06322 void ISQ_arrow_CB( MCW_arrowval * av , XtPointer client_data )
06323 {
06324    MCW_imseq * seq = (MCW_imseq *) client_data ;
06325    int ddd ;
06326 
06327 ENTRY("ISQ_arrow_CB") ;
06328 
06329    if( ! ISQ_REALZ(seq) ) EXRETURN ;
06330 
06331    if( av->fval > av->old_fval ) ddd = -1 ;
06332    else                          ddd =  1 ;
06333 
06334 
06335 
06336 
06337 
06338    if( av == seq->arrow[NARR_SQUEEZE] ){
06339            DC_palette_squeeze( seq->dc , ddd ) ;
06340            COLORMAP_CHANGE(seq) ;      
06341 
06342    } else if( av == seq->arrow[NARR_BRIGHT]  ){
06343            DC_palette_bright(  seq->dc , ddd ) ;
06344            COLORMAP_CHANGE(seq) ;      
06345 
06346    } else if( av == seq->arrow[NARR_ROTATE]  ){
06347            DC_palette_rotate(  seq->dc ,-ddd ) ;
06348            COLORMAP_CHANGE(seq) ;      
06349 
06350    } else if( av == seq->arrow[NARR_GAMMA]   ){
06351            if( seq->imim == NULL || seq->imim->kind != MRI_rgb ){
06352              double new_gamma = seq->dc->gamma ;
06353              if( ddd > 0 ) new_gamma *= 0.95 ;
06354              else          new_gamma /= 0.95 ;
06355              DC_palette_restore( seq->dc , new_gamma ) ;
06356              COLORMAP_CHANGE(seq) ;      
06357 
06358            } else {   
06359              if( ddd > 0 ) seq->rgb_gamma *= 0.95 ;
06360              else          seq->rgb_gamma /= 0.95 ;
06361              ISQ_redisplay( seq , -1 , isqDR_reimage ) ;
06362            }
06363 
06364    } else if( av == seq->arrow[NARR_FRAC]  ){  
06365       float nfrac = seq->image_frac ;
06366 
06367       nfrac += (ddd < 0) ? DFRAC : -DFRAC ;
06368 
06369       if( nfrac >= FRAC_MIN && nfrac <= FRAC_MAX ){
06370          seq->image_frac = nfrac ;
06371 
06372          XtVaSetValues( seq->wimage ,
06373                           XmNrightPosition ,(int)(0.49 + nfrac * FORM_FRAC_BASE),
06374                           XmNbottomPosition,(int)(0.49 + nfrac * FORM_FRAC_BASE),
06375                         NULL ) ;
06376          XtVaSetValues( seq->wscale ,
06377                           XmNrightPosition ,(int)(0.49 + nfrac * FORM_FRAC_BASE),
06378                         NULL ) ;
06379          XtVaSetValues( seq->wbar ,
06380                           XmNbottomPosition,(int)(0.49 + nfrac * FORM_FRAC_BASE),
06381                         NULL ) ;
06382          XtVaSetValues( seq->winfo ,
06383                           XmNrightPosition ,(int)(0.49 + nfrac * FORM_FRAC_BASE),
06384                         NULL ) ;
06385       } else {
06386          XBell( seq->dc->display , 100 ) ;
06387       }
06388    }
06389 
06390    ISQ_but_done_reset( seq ) ;
06391    EXRETURN ;
06392 }
06393 
06394 
06395 
06396 
06397 
06398 void ISQ_but_cnorm_CB( Widget w, XtPointer client_data, XtPointer call_data )
06399 {
06400    MCW_imseq *seq = (MCW_imseq *) client_data ;
06401 
06402 ENTRY("ISQ_but_cnorm_CB") ;
06403 
06404    if( ! ISQ_REALZ(seq) ) EXRETURN ;
06405 
06406    DC_palette_restore( seq->dc , 0.0 ) ;
06407    seq->rgb_gamma  = 1.0 ;     
06408    seq->rgb_offset = 0.0 ;
06409    COLORMAP_CHANGE(seq) ;      
06410    ISQ_but_done_reset( seq ) ;
06411    EXRETURN ;
06412 }
06413 
06414 
06415 
06416 
06417 
06418 
06419 
06420 
06421 
06422 
06423 
06424 
06425 
06426 
06427 
06428 
06429 
06430 
06431 
06432 
06433 
06434 
06435 
06436 
06437 
06438 
06439 
06440 
06441 
06442 
06443 
06444 
06445 
06446 
06447 
06448 
06449 
06450 
06451 
06452 
06453 
06454 
06455 
06456 
06457 
06458 
06459 
06460 
06461 
06462 
06463 
06464 
06465 
06466 
06467 
06468 
06469 
06470 
06471 
06472 
06473 
06474 
06475 
06476 
06477 
06478 
06479 
06480 
06481 
06482 
06483 
06484 
06485 
06486 
06487 
06488 
06489 
06490 
06491 
06492 
06493 
06494 
06495 
06496 
06497 
06498 
06499 
06500 
06501 
06502 
06503 
06504 
06505 
06506 
06507 
06508 
06509 
06510 
06511 
06512 
06513 
06514 
06515 
06516 
06517 
06518 
06519 
06520 
06521 
06522 
06523 
06524 
06525 
06526 
06527 
06528 
06529 
06530 
06531 
06532 
06533 
06534 
06535 
06536 
06537 
06538 
06539 
06540 
06541 
06542 
06543 
06544 
06545 
06546 
06547 
06548 
06549 
06550 Boolean drive_MCW_imseq( MCW_imseq * seq ,
06551                          int drive_code , XtPointer drive_data )
06552 {
06553 ENTRY("drive_MCW_imseq") ;
06554    if( ! ISQ_VALID(seq) ) RETURN( False );
06555 
06556    switch( drive_code ){
06557 
06558       
06559 
06560       default:{
06561          fprintf(stderr,"\a\n*** drive_MCW_imseq: code=%d illegal!\n",
06562                  drive_code) ;
06563          XBell( seq->dc->display , 100 ) ;
06564          RETURN( False );
06565       }
06566       break ;
06567 
06568       
06569 
06570       case isqDR_setrange:{
06571         float *rng = (float *)drive_data ;
06572         if( rng == NULL ){
06573           seq->rng_bot = seq->rng_top = seq->rng_ztop = 0.0f ;
06574         } else {
06575           seq->rng_bot = rng[0] ; seq->rng_top = rng[1] ; seq->rng_ztop = 0.0 ;
06576         }
06577         ISQ_redisplay( seq , -1 , isqDR_display ) ;
06578         RETURN( True ) ;
06579       }
06580       break ;
06581 
06582       
06583 
06584       case isqDR_setimsave:{
06585         char *suf = (char *)drive_data ;
06586         int ii ;
06587         if( suf == NULL || *suf == '\0' || ppmto_num < 1 ) RETURN(False) ;
06588         for( ii=0 ; ii < ppmto_num ; ii++ ){
06589           if( strcmp(suf  ,ppmto_suffix[ii]) == 0 ) break ;
06590           if( strcmp(suf+1,ppmto_suffix[ii]) == 0 ) break ;
06591         }
06592         if( ii == ppmto_num ) RETURN(False) ;
06593         seq->opt.save_filter = ii ;
06594         SET_SAVE_LABEL(seq) ;
06595         if( seq->num_bbox > 0 && seq->bbox[NTOG_SAV] != NULL )
06596           MCW_set_bbox( seq->bbox[NTOG_SAV] , ppmto_bval[ii] ) ;
06597         RETURN( True ) ;
06598       }
06599       break ;
06600 
06601       
06602 
06603       case isqDR_ignore_redraws:{
06604          int dd = (int)drive_data ;
06605          seq->ignore_redraws = dd ;
06606          RETURN( True ) ;
06607       }
06608       break ;
06609 
06610       
06611 
06612       case isqDR_plot_label:{
06613          int dd = (int)drive_data ;
06614 
06615          if( dd < 0 ){
06616             INVERT_manage( seq->wbar_label_av->wrowcol ) ;
06617             INVERT_manage( seq->wbar_labsz_av->wrowcol ) ;
06618          } else if( dd != seq->wbar_label_av->ival && dd >= 0 && dd <= 4 ){
06619            AV_assign_ival( seq->wbar_label_av , dd ) ;
06620            ISQ_redisplay( seq , -1 , isqDR_display ) ;
06621          }
06622          RETURN( True ) ;
06623       }
06624 
06625       
06626 
06627       case isqDR_save_jpeg:{                 
06628         char *fname = (char *)drive_data ;
06629         ISQ_save_jpeg( seq , fname ) ;
06630         RETURN( True ) ;
06631       }
06632 
06633       
06634 
06635       case isqDR_plot_plot:{
06636          int dd = (int)drive_data ;
06637 
06638          if( dd < 0 ){
06639             INVERT_manage( seq->wbar_plots_bbox->wrowcol ) ;
06640          } else {
06641             dd = (dd != 0) ;
06642             if( dd != MCW_val_bbox(seq->wbar_plots_bbox) ){
06643                MCW_set_bbox( seq->wbar_plots_bbox , dd ) ;
06644                ISQ_redisplay( seq , -1 , isqDR_display ) ;
06645             }
06646          }
06647          RETURN( True ) ;
06648       }
06649 
06650       
06651 
06652       case isqDR_record_disable:{
06653          ISQ_remove_widget( seq , seq->record_rc ) ;
06654          seq->record_status = RECORD_STATUS_OFF ;
06655          RETURN( True ) ;
06656       }
06657       break ;
06658 
06659       
06660 
06661       case isqDR_record_mode:{
06662          int ii ;
06663          static Pixmap record_pixmap = XmUNSPECIFIED_PIXMAP ;
06664 #define record_width 64
06665 #define record_height 32
06666 static unsigned char record_bits[] = {
06667    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
06668    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
06669    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x0f, 0x00, 0x00,
06670    0x00, 0x00, 0x00, 0x00, 0x81, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
06671    0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00,
06672    0x00, 0x00, 0x00, 0x02, 0x81, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
06673    0x81, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x81, 0x40, 0x00, 0x00,
06674    0x00, 0x00, 0x00, 0x02, 0x81, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
06675    0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x81, 0x10, 0x00, 0x00,
06676    0x00, 0x00, 0x00, 0x02, 0x81, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
06677    0x81, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x81, 0x10, 0x00, 0x00,
06678    0x00, 0x00, 0x00, 0x02, 0x81, 0x10, 0x70, 0x00, 0xe0, 0xf0, 0x01, 0x02,
06679    0x81, 0x20, 0x8c, 0xf0, 0x10, 0x21, 0xe2, 0x03, 0x81, 0x20, 0x02, 0x09,
06680    0x09, 0x22, 0x12, 0x02, 0x81, 0x20, 0x02, 0x09, 0x08, 0x22, 0x10, 0x02,
06681    0x81, 0x20, 0xfe, 0x09, 0x08, 0x22, 0x10, 0x02, 0x81, 0x40, 0x02, 0x08,
06682    0x08, 0x22, 0x10, 0x02, 0x81, 0x40, 0x02, 0x08, 0x08, 0x22, 0x10, 0x02,
06683    0x81, 0x40, 0x02, 0x08, 0x08, 0x22, 0x10, 0x02, 0x81, 0x40, 0x02, 0x08,
06684    0x08, 0x22, 0x10, 0x02, 0x81, 0x40, 0x04, 0x11, 0x11, 0x21, 0x20, 0x02,
06685    0x81, 0x40, 0xf8, 0xe0, 0xe0, 0x20, 0xc0, 0x01, 0x01, 0x00, 0x00, 0x00,
06686    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
06687    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
06688    0x00, 0x00, 0x00, 0x00};
06689 
06690          if( seq->record_mode ) RETURN( False ) ;  
06691          seq->record_mode = 1 ;
06692          seq->cropit = seq->crop_allowed = 0 ;     
06693 
06694          
06695 
06696          if( record_pixmap == XmUNSPECIFIED_PIXMAP )
06697             record_pixmap = XCreatePixmapFromBitmapData(
06698                               seq->dc->display ,
06699                               RootWindowOfScreen(seq->dc->screen) ,
06700                               record_bits, record_width, record_height ,
06701                               seq->dc->ovc->pixov_brightest ,
06702                               seq->dc->ovc->pixov_darkest ,
06703                               DefaultDepthOfScreen(seq->dc->screen) ) ;
06704 
06705          XtVaSetValues( seq->wform, XmNbackgroundPixmap, record_pixmap, NULL ) ;
06706 
06707          
06708 
06709          ISQ_remove_widget( seq , seq->wbut_bot[NBUT_MONT] ) ;
06710          ISQ_remove_widget( seq , seq->record_rc ) ;
06711          for( ii=0 ; ii < NBUTTON_RIG ; ii++)
06712             ISQ_remove_widget( seq , seq->wbut_rig[ii] ) ;
06713          for( ii=0 ; ii < NARROW-1 ; ii++ ) 
06714             ISQ_remove_widget( seq , seq->arrow[ii]->wrowcol ) ;
06715          if( seq->ov_opacity_av != NULL ){
06716             ISQ_remove_widget( seq , seq->ov_opacity_sep ) ;
06717             ISQ_remove_widget( seq , seq->ov_opacity_av->wrowcol ) ;
06718          }
06719 
06720          ISQ_remove_widget( seq , seq->zoom_sep ) ;
06721          ISQ_remove_widget( seq , seq->zoom_val_av->wrowcol ) ;
06722          ISQ_remove_widget( seq , seq->zoom_drag_pb ) ;
06723          ISQ_remove_widget( seq , seq->crop_drag_pb ) ;
06724          ISQ_remove_widget( seq , seq->pen_bbox->wrowcol ) ;
06725 
06726          ISQ_remove_widget( seq , seq->arrowpad->wform ) ;
06727          ISQ_remove_widget( seq , seq->wbar ) ;
06728          ISQ_remove_widget( seq , seq->winfo ) ;
06729 
06730          
06731 
06732          seq->opt.save_one    = 0 ;
06733          seq->opt.save_agif   = 0 ;   
06734          seq->opt.save_mpeg   = 0 ;
06735          seq->opt.save_pnm    = 0 ;
06736          seq->opt.save_filter = -1 ;  
06737          SET_SAVE_LABEL(seq) ;
06738          drive_MCW_imseq( seq , isqDR_setimsave ,
06739                           (XtPointer)getenv("AFNI_DEFAULT_IMSAVE") ) ;
06740 
06741          
06742 
06743          MCW_unregister_help( seq->wbut_bot[NBUT_DISP] ) ;
06744          if( ppmto_num > 0 ){
06745            MCW_register_help( seq->wbut_bot[NBUT_SAVE] ,
06746                                 "Save controls:\n"
06747                                 " Press with Button 1 (left) to save images\n"
06748                                 " Press with Button 3 (right) to change the\n"
06749                                 "   format of the saved images"
06750                             ) ;
06751            MCW_register_hint( seq->wbut_bot[NBUT_SAVE] ,
06752                               "Button 3 => change save format" ) ;
06753          } else {
06754            MCW_register_help( seq->wbut_bot[NBUT_SAVE] ,
06755                                 "Save controls:\n"
06756                                 " Press with Button 1 (left) to\n"
06757                                 " in the PNM format save images"  ) ;
06758            MCW_register_hint( seq->wbut_bot[NBUT_SAVE] ,
06759                               "Save images as PNM" ) ;
06760          }
06761 
06762          
06763 
06764          XtRemoveCallback( seq->wbut_bot[NBUT_DISP] , XmNactivateCallback ,
06765                            ISQ_but_bot_def[NBUT_DISP].func_CB , seq        ) ;
06766 
06767          XtAddCallback( seq->wbut_bot[NBUT_DISP] , XmNactivateCallback ,
06768                         ISQ_record_kill_CB , seq                       ) ;
06769 
06770          MCW_set_widget_label( seq->wbut_bot[NBUT_DISP] , "Kill" ) ;
06771          MCW_unregister_help( seq->wbut_bot[NBUT_DISP] ) ;
06772          MCW_register_hint( seq->wbut_bot[NBUT_DISP] , "Erase current image" ) ;
06773          MCW_register_help( seq->wbut_bot[NBUT_DISP] ,
06774                             "Erase the current image in the recorded sequence.\n"
06775                             "If not later overwritten, this image will NOT\n"
06776                             "be saved when you use Save:bkg to write the image\n"
06777                             "sequence to disk.\n"
06778                            ) ;
06779 
06780          
06781 
06782          XtVaSetValues( seq->wbut_bot[NBUT_DONE] ,
06783                            LEADING_BOT       , XmATTACH_WIDGET          ,
06784                            LEADING_WIDGET_BOT, seq->wbut_bot[NBUT_SAVE] ,
06785                         NULL ) ;
06786 
06787          
06788 
06789          XtVaSetValues( seq->wtop , XmNtitle , "Image Recorder" , NULL ) ;
06790          if( MCW_isitmwm( seq->wtop ) )
06791             XtVaSetValues( seq->wtop ,
06792                             XmNmwmDecorations, MWM_DECOR_ALL | MWM_DECOR_MAXIMIZE,
06793                            NULL ) ;
06794 
06795          RETURN( True ) ;
06796       }
06797       break ;
06798 
06799       
06800 
06801       case isqDR_opacitybut:{
06802          int val = (int) drive_data ;
06803          if( seq->ov_opacity_av == NULL ) RETURN( False ) ;
06804          if( val == 0 ){
06805             XtUnmanageChild( seq->ov_opacity_sep ) ;
06806             XtUnmanageChild( seq->ov_opacity_av->wrowcol ) ;
06807          }
06808          else {
06809             XtManageChild( seq->ov_opacity_sep ) ;
06810             XtManageChild( seq->ov_opacity_av->wrowcol ) ;
06811          }
06812          RETURN( True ) ;
06813       }
06814       break ;
06815 
06816       
06817 
06818       case isqDR_setopacity:{
06819         int val = (int) drive_data ;
06820         if( seq->ov_opacity_av == NULL ) RETURN( False ) ;
06821         if( val < OPACITY_BOT || val > OPACITY_TOP ) RETURN( False ) ;
06822         AV_assign_ival( seq->ov_opacity_av , val ) ;
06823         ISQ_opacity_CB( seq->ov_opacity_av , seq ) ;
06824         RETURN( True ) ;
06825       }
06826       break ;
06827 
06828       
06829 
06830       case isqDR_getopacity:{
06831         int *val = (int *) drive_data ;
06832         if( seq->ov_opacity_av == NULL || val == NULL ) RETURN( False ) ;
06833         *val = seq->ov_opacity_av->ival ;
06834         RETURN( True ) ;
06835       }
06836       break ;
06837 
06838       
06839 
06840       case isqDR_zoombut:{
06841          int val = (int) drive_data ;
06842          if( val == 0 ){
06843             XtUnmanageChild( seq->zoom_sep ) ;
06844             XtUnmanageChild( seq->zoom_val_av->wrowcol ) ;
06845             XtUnmanageChild( seq->zoom_drag_pb ) ;
06846             XtUnmanageChild( seq->crop_drag_pb ) ;
06847          } else {
06848             XtManageChild( seq->zoom_sep ) ;
06849             XtManageChild( seq->zoom_val_av->wrowcol ) ;
06850             XtManageChild( seq->zoom_drag_pb ) ;
06851             XtManageChild( seq->crop_drag_pb ) ;
06852          }
06853          RETURN( True ) ;
06854       }
06855       break ;
06856 
06857       
06858 
06859       case isqDR_penbbox:{
06860          int val = (int) drive_data ;
06861          if( val == 0 )
06862            XtUnmanageChild( seq->pen_bbox->wrowcol ) ;
06863          else
06864            XtManageChild( seq->pen_bbox->wrowcol ) ;
06865          RETURN( True ) ;
06866       }
06867       break ;
06868 
06869       
06870       
06871 
06872       case isqDR_setmontage:{
06873          int * mm = (int *) drive_data ;
06874 
06875          if( mm == NULL )                     RETURN( False );  
06876          if( mm[0] < 1 || mm[0] > MONT_NMAX ) RETURN( False );  
06877          if( mm[1] < 1 || mm[1] > MONT_NMAX ) RETURN( False );
06878 
06879          seq->mont_nx_old       = seq->mont_nx       ;  
06880          seq->mont_ny_old       = seq->mont_ny       ;
06881          seq->mont_skip_old     = seq->mont_skip     ;
06882          seq->mont_gap_old      = seq->mont_gap      ;
06883          seq->mont_gapcolor_old = seq->mont_gapcolor ;
06884 
06885          
06886 
06887          seq->mont_nx = mm[0] ;
06888          seq->mont_ny = mm[1] ;
06889          if( mm[2] >  0 && mm[2] <= MONT_SMAX ) seq->mont_skip     = mm[2]-1 ;
06890          if( mm[3] >= 0 && mm[3] <= MONT_GMAX ) seq->mont_gap      = mm[3] ;
06891          if( mm[4] >= 0 &&
06892              mm[4] <= seq->dc->ovc->ncol_ov-1 ) seq->mont_gapcolor = mm[4] ;
06893 
06894          
06895 
06896          if( seq->mont_nx * seq->mont_ny > 1 && !seq->opt.save_one ){
06897             seq->opt.save_one  = 1 ;
06898             seq->opt.save_agif = 0 ; 
06899             seq->opt.save_mpeg = 0 ;
06900             SET_SAVE_LABEL(seq) ;
06901          }
06902 
06903          
06904 
06905          ISQ_redisplay( seq , -1 , isqDR_display ) ;    
06906 
06907          if( seq->status->send_CB != NULL ){  
06908 
06909             ISQ_cbs cbs ;
06910             THD_ivec3 minf ;
06911             int ijcen = (seq->mont_nx)/2 + (seq->mont_ny/2) * seq->mont_nx ,
06912                 nmont = seq->mont_nx * seq->mont_ny ;
06913 
06914             minf.ijk[0]  = ijcen ;            
06915             minf.ijk[1]  = nmont-ijcen-1 ;    
06916             minf.ijk[2]  = seq->mont_skip ;   
06917             cbs.reason   = isqCR_newmontage ;
06918             cbs.userdata = (XtPointer) &minf ;
06919 
06920             seq->ignore_redraws = 1 ;         
06921 #if 0
06922             seq->status->send_CB( seq , seq->getaux , &cbs ) ;
06923 #else
06924             SEND(seq,cbs) ;
06925 #endif
06926             seq->ignore_redraws = 0 ;         
06927          }
06928 
06929 #if 0
06930          ISQ_redisplay( seq , -1 , isqDR_display ) ;    
06931 #endif
06932 
06933          RETURN( True );
06934       }
06935       break ;
06936 
06937       
06938 
06939       case isqDR_winfosides:{
06940          char ** ws = (char **) drive_data ;
06941          int iw ;
06942 
06943          if( ws == NULL ){                   
06944             seq->winfo_sides[0][0] =
06945              seq->winfo_sides[1][0] =
06946               seq->winfo_sides[2][0] =
06947                seq->winfo_sides[3][0] = '\0' ;
06948 
06949          } else {                           
06950             for( iw=0 ; iw < 4 ; iw++ ){
06951                if( ws[iw] == NULL || ws[iw][0] == '\0' ){
06952                   seq->winfo_sides[iw][0] = '\0' ;
06953                } else {
06954                   strncpy( seq->winfo_sides[iw] , ws[iw] , 15 ) ;
06955                   seq->winfo_sides[iw][15] = '\0' ;
06956                }
06957             }
06958          }
06959          seq->im_label[0] = '\0' ;  
06960          ISQ_draw_winfo( seq ) ;
06961 
06962          if( ws == NULL )                       
06963            MCW_unregister_hint( seq->winfo ) ;  
06964          else
06965            MCW_register_hint( seq->winfo ,
06966                     "setenv AFNI_LEFT_IS_LEFT YES disables 'radiology mode'" );
06967 
06968          RETURN( True );
06969       }
06970 
06971       
06972       
06973 
06974       case isqDR_setifrac:{
06975          float * ff = (float *) drive_data ;
06976 
06977          if( ff == NULL || *ff < FRAC_MIN || *ff > 1.0 ) RETURN( False );
06978 
06979          if( *ff <= FRAC_MAX ){ 
06980             float nfrac = *ff ;
06981             seq->image_frac = nfrac ;
06982 
06983             if( !seq->onoff_state )  
06984                drive_MCW_imseq( seq,isqDR_onoffwid,(XtPointer)isqDR_onwid );
06985 
06986             XtVaSetValues( seq->wimage ,
06987                              XmNrightPosition ,(int)(0.49+nfrac*FORM_FRAC_BASE),
06988                              XmNbottomPosition,(int)(0.49+nfrac*FORM_FRAC_BASE),
06989                            NULL ) ;
06990             XtVaSetValues( seq->wscale ,
06991                              XmNrightPosition ,(int)(0.49+nfrac*FORM_FRAC_BASE),
06992                            NULL ) ;
06993             XtVaSetValues( seq->wbar ,
06994                              XmNbottomPosition,(int)(0.49+nfrac*FORM_FRAC_BASE),
06995                            NULL ) ;
06996             XtVaSetValues( seq->winfo ,
06997                              XmNrightPosition ,(int)(0.49+nfrac*FORM_FRAC_BASE),
06998                            NULL ) ;
06999 
07000          } else if( seq->onoff_state ) {  
07001 
07002             drive_MCW_imseq( seq,isqDR_onoffwid,(XtPointer)isqDR_offwid );
07003 
07004          }
07005          RETURN( True );
07006       }
07007       break ;
07008 
07009       
07010 
07011       case isqDR_keypress:{
07012         unsigned int key = (unsigned int)drive_data ;
07013         (void )ISQ_handle_keypress( seq , key ) ;
07014         RETURN( True );
07015       }
07016       break ;
07017 
07018       
07019 
07020       case isqDR_winfotext:{
07021          char * wt = (char *) drive_data ;
07022 
07023          if( wt == NULL || wt[0] == '\0' ){
07024             seq->winfo_extra[0] = '\0' ;
07025          } else {
07026             strncpy( seq->winfo_extra , wt , 63 ) ;
07027             seq->winfo_extra[63] = '\0' ;
07028          }
07029          seq->im_label[0] = '\0' ;  
07030          ISQ_draw_winfo( seq ) ;
07031          RETURN( True );
07032       }
07033 
07034       
07035 
07036       case isqDR_button2_pixel:{
07037          seq->button2_pixel = (Pixel) drive_data ;
07038          RETURN( True );
07039       }
07040 
07041       case isqDR_button2_mode:{
07042          seq->button2_drawmode = (int) drive_data ;
07043          RETURN( True );
07044       }
07045 
07046       case isqDR_button2_width:{                  
07047          seq->button2_width = (int) drive_data ;
07048          RETURN( True );
07049       }
07050 
07051       case isqDR_button2_enable:{
07052          ISQ_timer_stop(seq) ;
07053          if( seq->status->send_CB == NULL ) RETURN( False );  
07054          if( seq->button2_enabled )         RETURN( True );   
07055 
07056          XtInsertEventHandler(
07057               seq->wimage ,         
07058 
07059                0
07060                | ButtonReleaseMask  
07061                | Button2MotionMask  
07062               ,
07063               FALSE ,               
07064               ISQ_button2_EV ,      
07065               (XtPointer) seq ,     
07066               XtListTail            
07067          ) ;
07068 
07069          seq->button2_enabled = 1 ;
07070          seq->button2_active  = 0 ;
07071 
07072          XtManageChild( seq->pen_bbox->wrowcol ) ;
07073          RETURN( True );
07074       }
07075 
07076       case isqDR_button2_disable:{
07077          if( seq->status->send_CB == NULL ) RETURN( False );  
07078          if( !seq->button2_enabled )        RETURN( True );   
07079 
07080          XtRemoveEventHandler(
07081               seq->wimage ,         
07082 
07083                0
07084                | ButtonReleaseMask  
07085                | Button2MotionMask  
07086               ,
07087               TRUE ,                
07088               ISQ_button2_EV ,      
07089               (XtPointer) seq       
07090          ) ;
07091 
07092          seq->button2_enabled = seq->button2_active = 0 ;
07093          ISQ_set_cursor_state( seq , CURSOR_NORMAL ) ;
07094          XtUnmanageChild( seq->pen_bbox->wrowcol ) ;
07095          RETURN( True );
07096       }
07097 
07098       
07099 
07100       case isqDR_periodicmont:{
07101         int per = ((int) drive_data) != 0 ;
07102 
07103         if( per != seq->mont_periodic ){
07104            seq->mont_periodic = per ;
07105            if( ISQ_REALZ(seq) ) ISQ_redisplay( seq , -1 , isqDR_display ) ;
07106         }
07107         RETURN( True );
07108       }
07109 
07110       case isqDR_sendmontage:{
07111          if( seq->status->send_CB != NULL ){
07112             ISQ_cbs cbs ;
07113             THD_ivec3 minf ;
07114             int ijcen = (seq->mont_nx)/2 + (seq->mont_ny/2) * seq->mont_nx ,
07115                 nmont = seq->mont_nx * seq->mont_ny ;
07116 
07117             minf.ijk[0]  = ijcen ;            
07118             minf.ijk[1]  = nmont-ijcen-1 ;    
07119             minf.ijk[2]  = seq->mont_skip ;   
07120             cbs.reason   = isqCR_newmontage ;
07121             cbs.userdata = (XtPointer) &minf ;
07122 #if 0
07123             seq->status->send_CB( seq , seq->getaux , &cbs ) ;
07124 #else
07125             SEND(seq,cbs) ;
07126 #endif
07127             RETURN( True );
07128          } else {
07129             RETURN( False );
07130          }
07131       }
07132       break ;
07133 
07134       
07135 
07136       case isqDR_icon:{
07137          XtVaSetValues( seq->wtop, XmNiconPixmap,(Pixmap)drive_data , NULL ) ;
07138          RETURN( True );
07139       }
07140       break ;
07141 
07142       
07143 
07144       case isqDR_bgicon:{
07145         XtVaSetValues( seq->wform,
07146                          XmNbackgroundPixmap, (Pixmap)drive_data ,
07147                        NULL ) ;
07148         RETURN( True );
07149       }
07150       break ;
07151 
07152       
07153 
07154       case isqDR_getimnr:{
07155          int * retval = (int *) drive_data ;
07156 
07157          if( retval != NULL ) *retval = seq->im_nr ;
07158          RETURN( True );
07159       }
07160       break ;
07161 
07162       
07163 
07164       case isqDR_onoffwid:{
07165          int mode = (int) drive_data , turn_on ;
07166          int ww , hh ;
07167 
07168          switch( mode ){
07169             default:
07170             case isqDR_togwid:  turn_on = ! seq->onoff_state ; break ;
07171             case isqDR_onwid:   turn_on = 1                  ; break ;
07172             case isqDR_offwid:  turn_on = 0                  ; break ;
07173          }
07174 
07175          if( turn_on == seq->onoff_state ) RETURN( True );
07176 
07177          MCW_widget_geom( seq->wimage , &ww , &hh , NULL,NULL ) ;
07178 
07179          if( turn_on ){
07180             MCW_manage_widgets( seq->onoff_widgets , seq->onoff_num ) ;
07181             XtVaSetValues(
07182                seq->wimage ,
07183                   XmNrightPosition ,(int)( 0.49+seq->image_frac*FORM_FRAC_BASE ),
07184                   XmNbottomPosition,(int)( 0.49+seq->image_frac*FORM_FRAC_BASE ),
07185                NULL ) ;
07186             XtVaSetValues( seq->wtop ,
07187                               XmNwidth  , (int)(0.49+ww/seq->image_frac) ,
07188                               XmNheight , (int)(0.49+hh/seq->image_frac) ,
07189                            NULL ) ;
07190             if( !seq->button2_enabled ) XtUnmanageChild(seq->pen_bbox->wrowcol);
07191          } else {
07192             MCW_unmanage_widgets( seq->onoff_widgets , seq->onoff_num ) ;
07193             XtVaSetValues( seq->wimage ,
07194                               XmNrightPosition , FORM_FRAC_BASE ,
07195                               XmNbottomPosition, FORM_FRAC_BASE ,
07196                            NULL ) ;
07197             XtVaSetValues( seq->wtop ,
07198                               XmNwidth  , ww ,
07199                               XmNheight , hh ,
07200                            NULL ) ;
07201          }
07202 
07203          seq->onoff_state = turn_on ;
07204          RETURN( True );
07205       }
07206       break ;
07207 
07208       
07209 
07210       case isqDR_title:{
07211          char * title = (char *) drive_data ;
07212 
07213          if( title == NULL || strlen(title) == 0 ) title = "AFNI" ;
07214 
07215          XtVaSetValues( seq->wtop , XmNtitle , title , NULL ) ;
07216 #if 1
07217          if( MCW_isitmwm( seq->wtop ) )
07218             XtVaSetValues( seq->wtop ,
07219                             XmNmwmDecorations, MWM_DECOR_ALL | MWM_DECOR_MAXIMIZE,
07220                            NULL ) ;
07221 #endif
07222          RETURN( True );
07223       }
07224       break ;
07225 
07226       
07227 
07228       case isqDR_destroy:{
07229          ISQ_timer_stop(seq) ;
07230          ISQ_but_done_CB( NULL , (XtPointer) seq , NULL ) ;
07231          RETURN( True );
07232       }
07233       break ;
07234 
07235       
07236 
07237       case isqDR_unrealize:{
07238          ISQ_timer_stop(seq) ;
07239          if( ISQ_REALZ(seq) ) XtUnrealizeWidget( seq->wtop ) ;
07240          seq->valid = 1 ;
07241          RETURN( True );
07242       }
07243       break ;
07244 
07245       
07246 
07247       case isqDR_realize:{
07248          if( ! ISQ_REALZ(seq) ){
07249             XtRealizeWidget( seq->wtop ) ;
07250             WAIT_for_window( seq->wtop ) ;
07251             NORMAL_cursorize( seq->wtop ) ;
07252             POPUP_cursorize( seq->wimage ) ;
07253             POPUP_cursorize( seq->wbar ) ;
07254             POPUP_cursorize( seq->wbut_bot[NBUT_SAVE] ) ;
07255             XmUpdateDisplay( seq->wtop ) ;
07256          }
07257 #ifndef DONT_ONOFF_ONE
07258          if( seq->status->num_total == 1 )  
07259             drive_MCW_imseq( seq , isqDR_onoffwid , (XtPointer) isqDR_offwid ) ;
07260 #endif
07261          seq->valid = 2 ;
07262          RETURN( True );
07263       }
07264       break ;
07265 
07266       
07267 
07268       case isqDR_imhelptext:{
07269         char * newtxt = (char *) drive_data ;
07270         int ii ;
07271 
07272         if( newtxt == NULL ) RETURN( False );
07273         ii = strlen(newtxt) ;
07274         if( ii == 0 ) RETURN( False );
07275 
07276         strncpy( seq->im_helptext , newtxt , ISQ_NHELP ) ;
07277         seq->im_helptext[ISQ_NHELP] = '\0' ;
07278         RETURN( True );
07279       }
07280       break ;
07281 
07282       
07283 
07284       case isqDR_reimage:
07285       case isqDR_reshow:
07286       case isqDR_overlay:
07287       case isqDR_display:{
07288          int n = (int) drive_data ;
07289 
07290          if( ! seq->ignore_redraws )
07291             ISQ_redisplay( seq , n , drive_code ) ;
07292          RETURN( True );
07293       }
07294       break ;
07295 
07296       
07297 
07298       case isqDR_rebar:{
07299          KILL_2XIM( seq->given_xbar , seq->sized_xbar ) ; 
07300          if( seq->onoff_state ) ISQ_show_bar( seq ) ;     
07301          RETURN( True );
07302       }
07303       break ;
07304 
07305       
07306 
07307       case isqDR_cursor:{
07308          int cur = (int) drive_data ;
07309 
07310          MCW_alter_widget_cursor( seq->wimage , cur , "yellow" , "blue" ) ;
07311          RETURN( True );
07312       }
07313       break ;
07314 
07315       
07316 
07317       case isqDR_options:{
07318          ISQ_options * newopt = (ISQ_options *) drive_data ;
07319          int sf ;
07320 
07321          if( ppmto_num > 0 )           
07322            sf = seq->opt.save_filter ; 
07323 
07324          if( newopt != NULL ) seq->opt = *newopt ;
07325 
07326          if( ppmto_num > 0 )
07327            seq->opt.save_filter = sf ;
07328 
07329          seq->opt.parent = (XtPointer) seq ;
07330          SET_SAVE_LABEL(seq) ;
07331          AV_SENSITIZE(seq->ov_opacity_av,!seq->opt.no_overlay) ; 
07332 
07333 
07334          seq->im_label[0] = '\0' ;  
07335          if( ISQ_REALZ(seq) ) ISQ_redisplay( seq , -1 , isqDR_display ) ;
07336          RETURN( True );
07337       }
07338       break ;
07339 
07340       
07341 
07342       case isqDR_getoptions:{
07343          ISQ_options * opt = (ISQ_options *) drive_data ;
07344 
07345          if( opt == NULL ) RETURN( False );
07346          *opt = seq->opt ;
07347          RETURN( True );
07348       }
07349 
07350       
07351 
07352       case isqDR_arrowpadon:{
07353          char * helptext = (char *) drive_data ;
07354 
07355          XtSetMappedWhenManaged( seq->arrowpad->wform , True ); 
07356 
07357          if( helptext != NULL && strlen(helptext) > 0 ){
07358             char * str = XtNewString( helptext ) ;
07359             MCW_reghelp_children( seq->arrowpad->wform , str ) ;
07360             XtFree(str) ;  
07361          }
07362          RETURN( True );
07363       }
07364       break ;
07365 
07366       case isqDR_arrowpadhint:{
07367          int ib ;
07368          char ** hint = (char **) drive_data ;
07369          if( hint == NULL ) RETURN( False );
07370          for( ib=0 ; ib < 5 ; ib++ )
07371             MCW_register_hint( seq->arrowpad->wbut[ib] , hint[ib] ) ;
07372          RETURN( True );
07373       }
07374       break ;
07375 
07376       
07377 
07378       case isqDR_arrowpadoff:{
07379          XtSetMappedWhenManaged( seq->arrowpad->wform , False ); 
07380          RETURN( True );
07381       }
07382       break ;
07383 
07384       
07385 
07386 #if 0                                   
07387       case isqDR_numtotal:{
07388          int newtot = (int) drive_data ,
07389              oldtot = seq->status->num_total ,
07390              numser = seq->status->num_series , ii ;
07391          char * msg =
07392              "illegal change to image\n"
07393              "count from driver routine\n"
07394              "(press here to continue)" ;
07395 
07396          
07397 
07398          if( newtot == oldtot ) RETURN( True );
07399 
07400          if( newtot < 2 || newtot < numser ){
07401             if( ISQ_REALZ(seq) )
07402                MCW_popup_message( seq->wimage , msg , MCW_USER_KILL ) ;
07403             fprintf(stderr,"\n%s\n",msg) ;
07404             RETURN( False );
07405          }
07406 
07407          
07408 
07409          if( seq->glstat->worker != 0 ){
07410             XtRemoveWorkProc( seq->glstat->worker ) ;
07411             seq->glstat->worker = 0 ;
07412          }
07413 
07414          
07415 
07416          seq->imstat = (ISQ_indiv_statistics *)
07417                         XtRealloc( (char *) seq->imstat ,
07418                                    sizeof(ISQ_indiv_statistics) * newtot ) ;
07419 
07420          for( ii=oldtot ; ii < newtot ; ii++ )
07421              seq->imstat[ii].one_done = seq->imstat[ii].glob_done = False ;
07422 
07423          
07424 
07425          seq->status->num_total = newtot ;
07426 
07427          XtVaSetValues( seq->wscale ,
07428                            XmNmaximum , newtot-1 ,
07429                         NULL ) ;
07430 
07431          if( seq->im_nr >= newtot )
07432             ISQ_redisplay( seq , newtot-1 , isqDR_display ) ;
07433 
07434          RETURN( True );
07435       }
07436       break ;
07437 #endif
07438 
07439       
07440 
07441       case isqDR_newseq:{
07442          Boolean good ;
07443          ISQ_timer_stop(seq) ;
07444          good = ISQ_setup_new( seq , drive_data ) ;
07445          RETURN( good );
07446       }
07447       break ;
07448 
07449       
07450 
07451       case isqDR_clearstat:{
07452          int ii ;
07453 
07454          seq->opt.scale_group = ISQ_SCL_AUTO ;  
07455          ISQ_disp_options( seq , False ) ;      
07456 
07457          if( seq->glstat->worker != 0 ){  
07458             XtRemoveWorkProc( seq->glstat->worker ) ;
07459             seq->glstat->worker = 0 ;
07460          }
07461 
07462          for( ii=0 ; ii < seq->status->num_total ; ii++ )
07463             seq->imstat[ii].one_done = seq->imstat[ii].glob_done = False ;
07464 
07465          for( ii=0 ; ii < NHISTOG ; ii++ )
07466             seq->glstat->hist[ii] = 0 ;  
07467 
07468          seq->glstat->mm_done =
07469            seq->glstat->per_done = (seq->status->num_series < 2 ) ;
07470 
07471 #ifdef AUTOMATE_STATISTICS
07472          if( seq->glstat->mm_done ){
07473             seq->glstat->worker = 0 ;
07474          } else {
07475             seq->glstat->worker = XtAppAddWorkProc(
07476                                         seq->dc->appcontext ,
07477                                         ISQ_statistics_WP , seq ) ;
07478          }
07479 #else
07480          seq->glstat->worker = 0 ;
07481 #endif
07482       }
07483       break ;
07484 
07485    }  
07486 
07487    RETURN( False );  
07488 }
07489 
07490 
07491 
07492 #define XYORG 128
07493 #define DXY    64
07494 
07495 void ISQ_arrowpad_CB( MCW_arrowpad * apad , XtPointer client_data )
07496 {
07497    MCW_imseq * seq = (MCW_imseq *) client_data ;
07498 
07499    ISQ_cbs cbs ;
07500    int xorg,yorg , xwin,ywin , xoff,yoff ;
07501 
07502 ENTRY("ISQ_arrowpad_CB") ;
07503 
07504    if( ! ISQ_REALZ(seq) || seq->status->send_CB == NULL ) EXRETURN ;
07505 
07506    cbs.event = &(apad->xev) ;  
07507 
07508    if( apad->which_pressed == AP_MID ){
07509       cbs.reason = isqCR_appress ;
07510 #if 0
07511       seq->status->send_CB( seq , seq->getaux , &cbs ) ;
07512 #else
07513       SEND(seq,cbs) ;
07514 #endif
07515       EXRETURN ;
07516    }
07517 
07518    
07519 
07520    if( seq->zoom_button1 && seq->zoom_fac > 1 && seq->zoom_xim != NULL ){
07521      switch( apad->which_pressed ){
07522        default:
07523        case AP_DOWN:  xoff =  0 ; yoff = -1 ; break ;
07524        case AP_UP:    xoff =  0 ; yoff =  1 ; break ;
07525        case AP_LEFT:  xoff =  1 ; yoff =  0 ; break ;
07526        case AP_RIGHT: xoff = -1 ; yoff =  0 ; break ;
07527      }
07528      ISQ_actually_pan( seq , xoff , yoff ) ;
07529      EXRETURN ;
07530    }
07531 
07532    xwin = ywin = XYORG ;
07533 
07534    switch( apad->which_pressed ){
07535       default:
07536       case AP_DOWN:  ywin = XYORG + DXY ; break ;
07537       case AP_UP:    ywin = XYORG - DXY ; break ;
07538       case AP_LEFT:  xwin = XYORG - DXY ; break ;
07539       case AP_RIGHT: xwin = XYORG + DXY ; break ;
07540    }
07541 
07542    xorg = yorg = XYORG ;       ISQ_flipxy( seq , &xorg,&yorg ) ;
07543    xoff = xwin ; yoff = ywin ; ISQ_flipxy( seq , &xoff,&yoff ) ;
07544 
07545         if( xoff > xorg ) cbs.reason = isqCR_dxplus  ;
07546    else if( xoff < xorg ) cbs.reason = isqCR_dxminus ;
07547    else if( yoff > yorg ) cbs.reason = isqCR_dyplus  ;
07548    else if( yoff < yorg ) cbs.reason = isqCR_dyminus ;
07549    else                   EXRETURN ;                     
07550 
07551 #if 0
07552    seq->status->send_CB( seq , seq->getaux , &cbs ) ;
07553 #else
07554    SEND(seq,cbs) ;
07555 #endif
07556    EXRETURN ;
07557 }
07558 
07559 
07560 
07561 
07562 
07563 
07564 
07565 Boolean ISQ_setup_new( MCW_imseq * seq , XtPointer newaux )
07566 {
07567    MCW_imseq_status * imstatus ;
07568    int ii ;
07569    MRI_IMAGE * tim ;
07570 
07571 ENTRY("ISQ_setup_new") ;
07572 
07573    if( !ISQ_VALID(seq) ) RETURN( False );
07574 
07575 #if 0
07576    imstatus = (MCW_imseq_status *) seq->getim(0,isqCR_getstatus,newaux);
07577 #else
07578    AFNI_CALL_VALU_3ARG( seq->getim , MCW_imseq_status *,imstatus ,
07579                         int,0 , int,isqCR_getstatus , XtPointer,newaux ) ;
07580 #endif
07581    if( imstatus->num_total < 1 ){ RETURN( False ); }  
07582 
07583 #if 0
07584    tim = (MRI_IMAGE *) seq->getim(0,isqCR_getqimage,newaux) ; 
07585    KILL_1MRI(tim) ;  
07586 #endif
07587 
07588 #if 1
07589    if( seq->status != NULL ) myXtFree(seq->status) ;  
07590 #endif
07591 
07592    seq->status = imstatus ;
07593    seq->im_nr  = imstatus->num_total / 2 ;  
07594 
07595    KILL_1MRI(seq->imim) ;  
07596    KILL_1MRI(seq->ovim) ;
07597    KILL_1MRI(seq->orim) ;  
07598 
07599    KILL_2XIM( seq->given_xim  , seq->sized_xim  ) ;
07600    KILL_2XIM( seq->given_xbar , seq->sized_xbar ) ;
07601 
07602    seq->given_xim = seq->sized_xim
07603                   = seq->given_xbar
07604                   = seq->sized_xbar = NULL ;
07605 
07606    seq->imim = seq->ovim = NULL ;
07607 
07608    
07609 
07610    seq->opt.scale_group = ISQ_SCL_AUTO ;
07611    ISQ_disp_options( seq , False ) ;  
07612 
07613    seq->imstat = (ISQ_indiv_statistics *)
07614                  XtRealloc( (char *) seq->imstat ,
07615                             sizeof(ISQ_indiv_statistics)
07616                             * imstatus->num_total ) ;
07617 
07618    if( seq->glstat->worker != 0 ){  
07619       XtRemoveWorkProc( seq->glstat->worker ) ;
07620       seq->glstat->worker = 0 ;
07621    }
07622 
07623    for( ii=0 ; ii < imstatus->num_total ; ii++ ){
07624       seq->imstat[ii].one_done = seq->imstat[ii].glob_done = False ;
07625       seq->imstat[ii].parent   = (XtPointer) seq ;
07626    }
07627    seq->glstat->parent = (XtPointer) seq ;
07628 
07629    for( ii=0 ; ii < NHISTOG ; ii++ )
07630       seq->glstat->hist[ii] = 0 ;  
07631 
07632    seq->glstat->mm_done =
07633      seq->glstat->per_done = (seq->status->num_series < 2 ) ;
07634 
07635 #ifdef AUTOMATE_STATISTICS
07636    if( seq->glstat->mm_done ){
07637       seq->glstat->worker = 0 ;
07638    } else {
07639       seq->glstat->worker = XtAppAddWorkProc(
07640                                   seq->dc->appcontext ,
07641                                   ISQ_statistics_WP , seq ) ;
07642    }
07643 #else
07644    seq->glstat->worker = 0 ;
07645 #endif
07646 
07647    
07648 
07649    ii = seq->status->num_total - 1 ; if( ii <= 0 ) ii = 1 ;  
07650 
07651    XtVaSetValues( seq->wscale ,
07652                      XmNmaximum , ii ,
07653                      XmNvalue   , seq->im_nr ,
07654                   NULL ) ;
07655 
07656 #ifndef DONT_ONOFF_ONE
07657    if( seq->status->num_total == 1 )
07658       drive_MCW_imseq( seq , isqDR_onoffwid , (XtPointer) isqDR_offwid ) ;
07659 #endif
07660 
07661  if(PRINT_TRACING){
07662    char str[256] ;
07663    sprintf(str,"hbase=%d vbase=%d nim=%d lev=%g",
07664           seq->hbase,seq->vbase, seq->status->num_total,seq->lev ) ;
07665    STATUS(str) ;
07666  }
07667 
07668    seq->getaux = newaux ;
07669 
07670    RETURN( True ) ;
07671 }
07672 
07673 
07674 
07675 
07676 void ISQ_wbar_plots_CB( Widget w , XtPointer cld , XtPointer cad ) 
07677 {
07678    MCW_imseq * seq = (MCW_imseq *) cld ;
07679 
07680 ENTRY("ISQ_wbar_plots_CB") ;
07681 
07682    if( !ISQ_REALZ(seq) ) EXRETURN ;
07683    ISQ_redisplay( seq , -1 , isqDR_display ) ;
07684    EXRETURN ;
07685 }
07686 
07687 
07688 
07689 void ISQ_wbar_label_CB( MCW_arrowval *av , XtPointer cd )
07690 {
07691    MCW_imseq * seq = (MCW_imseq *) cd ;
07692 
07693 ENTRY("ISQ_wbar_label_CB") ;
07694 
07695    if( !ISQ_REALZ(seq) ) EXRETURN ;
07696    ISQ_redisplay( seq , -1 , isqDR_display ) ;
07697    EXRETURN ;
07698 }
07699 
07700 
07701 
07702 void ISQ_wbar_menu_CB( Widget w , XtPointer client_data ,
07703                                   XtPointer call_data    )
07704 {
07705    MCW_imseq * seq = (MCW_imseq *) client_data ;
07706 
07707 ENTRY("ISQ_wbar_menu_CB") ;
07708 
07709    if( ! ISQ_REALZ(seq) ) EXRETURN ;
07710 
07711    
07712 
07713    if( w == seq->wbar_rng_but ){
07714       MCW_choose_string( seq->wimage , "Display range: bot top [ztop]" ,
07715                          NULL , ISQ_set_rng_CB , seq ) ;
07716    }
07717 
07718    else if( w == seq->wbar_zer_but ){
07719       MCW_choose_ovcolor( seq->wimage , seq->dc , seq->zer_color ,
07720                           ISQ_set_zcol_CB , seq ) ;
07721    }
07722 
07723    else if( w == seq->wbar_flat_but ){
07724       MCW_choose_string( seq->wimage , "Flatten range: bot top" ,
07725                          NULL , ISQ_set_flat_CB , seq ) ;
07726    }
07727 
07728    else if( w == seq->wbar_sharp_but ){
07729       MCW_choose_integer( seq->wimage , "Sharpen Factor" ,
07730                           1 , 9 , (int)(10*seq->sharp_fac) ,
07731                           ISQ_set_sharp_CB , seq ) ;
07732    }
07733 
07734    else if( w == seq->wbar_graymap_pb ){   
07735      ISQ_graymap_draw( seq ) ;
07736    }
07737 
07738    EXRETURN ;
07739 }
07740 
07741 
07742 
07743 void ISQ_set_rng_CB( Widget w , XtPointer cd , MCW_choose_cbs * cbs )
07744 {
07745    MCW_imseq * seq = (MCW_imseq *) cd ;
07746 
07747 ENTRY("ISQ_set_rng_CB") ;
07748 
07749    if( ! ISQ_REALZ(seq) || w == NULL || ! XtIsWidget(w) ) EXRETURN ;
07750 
07751    seq->rng_bot = seq->rng_top = seq->rng_ztop = 0.0 ;
07752    sscanf( cbs->cval , "%f%f%f" ,
07753            &(seq->rng_bot) , &(seq->rng_top) , &(seq->rng_ztop) ) ;
07754    ISQ_redisplay( seq , -1 , isqDR_reimage ) ;  
07755    EXRETURN ;
07756 }
07757 
07758 
07759 
07760 void ISQ_set_zcol_CB( Widget w , XtPointer cd , MCW_choose_cbs * cbs )
07761 {
07762    MCW_imseq * seq = (MCW_imseq *) cd ;
07763 
07764 ENTRY("ISQ_set_zcol_CB") ;
07765 
07766    if( ! ISQ_REALZ(seq) || w == NULL || ! XtIsWidget(w) ) EXRETURN ;
07767 
07768    seq->zer_color = cbs->ival ;
07769    ISQ_redisplay( seq , -1 , isqDR_reimage ) ;  
07770    EXRETURN ;
07771 }
07772 
07773 
07774 
07775 void ISQ_set_flat_CB( Widget w , XtPointer cd , MCW_choose_cbs * cbs )
07776 {
07777    MCW_imseq * seq = (MCW_imseq *) cd ;
07778 
07779 ENTRY("ISQ_set_flat_CB") ;
07780 
07781    if( ! ISQ_REALZ(seq) || w == NULL || ! XtIsWidget(w) ) EXRETURN ;
07782 
07783    seq->flat_bot = seq->flat_top = 0.0 ;
07784    sscanf( cbs->cval , "%f%f" ,
07785            &(seq->flat_bot) , &(seq->flat_top) ) ;
07786 
07787    if( seq->flat_bot < 0.0 ) seq->flat_bot = 0.0 ;
07788    if( seq->flat_bot > 1.0 ) seq->flat_bot*= 0.01 ;
07789    if( seq->flat_top < 0.0 ) seq->flat_top = 0.0 ;
07790    if( seq->flat_top > 1.0 ) seq->flat_top*= 0.01 ;
07791 
07792    if( seq->flat_bot >= seq->flat_top || seq->flat_top > 1.0 )
07793       seq->flat_bot = seq->flat_top = 0.0 ;
07794 
07795    ISQ_redisplay( seq , -1 , isqDR_reimage ) ;  
07796    EXRETURN ;
07797 }
07798 
07799 
07800 
07801 void ISQ_set_sharp_CB( Widget w , XtPointer cd , MCW_choose_cbs * cbs )
07802 {
07803    MCW_imseq * seq = (MCW_imseq *) cd ;
07804 
07805 ENTRY("ISQ_set_sharp_CB") ;
07806 
07807    if( ! ISQ_REALZ(seq) || w == NULL || ! XtIsWidget(w) ) EXRETURN ;
07808 
07809    seq->sharp_fac = 0.1 * cbs->ival ;
07810 
07811    ISQ_redisplay( seq , -1 , isqDR_reimage ) ;  
07812    EXRETURN ;
07813 }
07814 
07815 
07816 
07817 
07818 
07819 #define MONT_quit_label  "Quit"
07820 #define MONT_1x1_label   "1x1"
07821 #define MONT_apply_label "Draw"
07822 #define MONT_done_label  "Set"
07823 
07824 #define MONT_quit_help   "Press to close\nthis control box"
07825 #define MONT_1x1_help    "Press to set the controls\nto Across=1 and Down=1"
07826 #define MONT_apply_help  "Press to apply this choice\nand keep this control box"
07827 #define MONT_done_help   "Press to apply this choice\nand close this control box"
07828 
07829 #define NUM_MONT_ACT 4
07830 
07831 static MCW_action_item MONT_act[NUM_MONT_ACT] = {
07832  { MONT_quit_label , ISQ_montage_action_CB, NULL, MONT_quit_help ,"Close window"                 ,0 },
07833  { MONT_1x1_label  , ISQ_montage_action_CB, NULL, MONT_1x1_help  ,"Set Across=Down=1"            ,0 },
07834  { MONT_apply_label, ISQ_montage_action_CB, NULL, MONT_apply_help,"Apply choice and keep window" ,0 },
07835  { MONT_done_label , ISQ_montage_action_CB, NULL, MONT_done_help ,"Apply choice and close window",1 },
07836 } ;
07837 
07838 #define MONT_QUIT  0
07839 #define MONT_1X1   1
07840 #define MONT_APPLY 2
07841 #define MONT_DONE  3
07842 
07843 void ISQ_montage_CB( Widget w, XtPointer client_data, XtPointer call_data )
07844 {
07845    MCW_imseq * seq = (MCW_imseq *) client_data ;
07846    int ib ;
07847    Widget wrc ;
07848 
07849 ENTRY("ISQ_montage_CB") ;
07850 
07851    if( ! ISQ_REALZ(seq) || seq->dialog != NULL ) EXRETURN ;
07852 
07853    if( seq->zoom_fac != 1 ){
07854 #if 0
07855 fprintf(stderr,"montage: zoom_fac = %d\n",seq->zoom_fac) ;
07856 #endif
07857      XBell(seq->dc->display,100); EXRETURN; 
07858    }
07859 
07860    for( ib=0 ; ib < NBUTTON_BOT-1 ; ib++ )       
07861      if( ISQ_but_bot_dial[ib] == True )          
07862        SENSITIZE( seq->wbut_bot[ib] , False ) ;  
07863 
07864    seq->dialog = XtVaCreatePopupShell(
07865                     "menu" , xmDialogShellWidgetClass , seq->wtop ,
07866                        XmNtitle , "Montage" ,
07867                        XmNdeleteResponse , XmDO_NOTHING ,
07868                        XmNinitialResourcesPersistent , False ,
07869                     NULL ) ;
07870 
07871    SAVEUNDERIZE(seq->dialog) ; 
07872 
07873    DC_yokify( seq->dialog , seq->dc ) ; 
07874 
07875    seq->dialog_starter = NBUT_MONT ;
07876 
07877 #if 1
07878    if( MCW_isitmwm(w) )
07879       XtVaSetValues( seq->dialog ,
07880                        XmNmwmDecorations , MWM_DECOR_BORDER ,
07881                        XmNmwmFunctions ,   MWM_FUNC_MOVE
07882                                          | MWM_FUNC_CLOSE ,
07883                      NULL ) ;
07884 #endif
07885 
07886    XmAddWMProtocolCallback(           
07887            seq->dialog ,
07888            XmInternAtom( seq->dc->display , "WM_DELETE_WINDOW" , False ) ,
07889            ISQ_montage_action_CB , seq ) ;
07890 
07891    wrc  = XtVaCreateWidget(                    
07892              "menu" , xmRowColumnWidgetClass , seq->dialog ,
07893                 XmNpacking     , XmPACK_TIGHT ,
07894                 XmNorientation , XmVERTICAL ,
07895                 XmNtraversalOn , False ,
07896                 XmNinitialResourcesPersistent , False ,
07897              NULL ) ;
07898 
07899    (void) XtVaCreateManagedWidget(
07900             "menu" , xmLabelWidgetClass , wrc ,
07901                LABEL_ARG("-- Montage Controls --") ,
07902                XmNalignment  , XmALIGNMENT_CENTER ,
07903                XmNinitialResourcesPersistent , False ,
07904             NULL ) ;
07905 
07906    (void) XtVaCreateManagedWidget(
07907             "menu" , xmSeparatorWidgetClass , wrc ,
07908                XmNseparatorType , XmSHADOW_ETCHED_IN ,
07909                XmNinitialResourcesPersistent , False ,
07910             NULL ) ;
07911 
07912    seq->mont_across_av = new_MCW_arrowval(
07913 #if 1
07914                           wrc , "Across:" ,
07915 #else
07916                           wrc , NULL ,   
07917 #endif
07918                           MCW_AV_optmenu ,
07919                           1 , MONT_NMAX , seq->mont_nx ,
07920                           MCW_AV_edittext , 0 ,
07921                           NULL , NULL , NULL , NULL ) ;
07922 
07923    if( MONT_NMAX > COLSIZE )
07924       AVOPT_columnize(  seq->mont_across_av , 1+(MONT_NMAX-1)/COLSIZE ) ;
07925 
07926    if( seq->mont_across_av->wtext != NULL )
07927       XtVaSetValues( seq->mont_across_av->wtext , XmNcolumns , 4 , NULL ) ;
07928 
07929    seq->mont_down_av  = new_MCW_arrowval(
07930                           wrc , "Down:  " ,
07931                           MCW_AV_optmenu ,
07932                           1 , MONT_NMAX , seq->mont_ny ,
07933                           MCW_AV_edittext , 0 ,
07934                           NULL , NULL , NULL , NULL ) ;
07935 
07936    if( MONT_NMAX > COLSIZE )
07937       AVOPT_columnize(  seq->mont_down_av , 1+(MONT_NMAX-1)/COLSIZE ) ;
07938 
07939    if( seq->mont_down_av->wtext != NULL )
07940       XtVaSetValues( seq->mont_down_av->wtext , XmNcolumns , 4 , NULL ) ;
07941 
07942    seq->mont_skip_av  = new_MCW_arrowval(
07943                           wrc , "Spacing" ,
07944                           MCW_AV_optmenu ,
07945                           1 , MONT_SMAX , seq->mont_skip + 1 ,
07946                           MCW_AV_edittext , 0 ,
07947                           NULL , NULL , NULL , NULL ) ;
07948 
07949    if( MONT_SMAX > COLSIZE )
07950       AVOPT_columnize(  seq->mont_skip_av , 1+(MONT_SMAX-1)/COLSIZE ) ;
07951 
07952    if( seq->mont_skip_av->wtext != NULL )
07953       XtVaSetValues( seq->mont_skip_av->wtext , XmNcolumns , 4 , NULL ) ;
07954 
07955    seq->mont_gap_av  = new_MCW_arrowval(
07956                           wrc , "Border:" ,
07957                           MCW_AV_optmenu ,
07958                           0 , MONT_GMAX , seq->mont_gap,
07959                           MCW_AV_edittext , 0 ,
07960                           NULL , NULL , NULL , NULL ) ;
07961 
07962    if( MONT_GMAX > COLSIZE )
07963       AVOPT_columnize(  seq->mont_gap_av , 1+(MONT_GMAX-1)/COLSIZE ) ;
07964 
07965    if( seq->mont_gap_av->wtext != NULL )
07966       XtVaSetValues( seq->mont_gap_av->wtext , XmNcolumns , 4 , NULL ) ;
07967 
07968    seq->mont_gapcolor_av = new_MCW_colormenu( wrc ,
07969                                 "Color: " , seq->dc ,
07970                                 0 , seq->dc->ovc->ncol_ov - 1 , seq->mont_gapcolor ,
07971                                 NULL , NULL ) ;
07972 
07973    seq->mont_across_av->allow_wrap   = 1 ;   
07974    seq->mont_down_av->allow_wrap     = 1 ;
07975    seq->mont_skip_av->allow_wrap     = 1 ;
07976    seq->mont_gap_av->allow_wrap      = 1 ;
07977    seq->mont_gapcolor_av->allow_wrap = 1 ;
07978 
07979    seq->mont_across_av->fastdelay    = 250 ; 
07980    seq->mont_down_av->fastdelay      = 250 ;
07981    seq->mont_skip_av->fastdelay      = 250 ;
07982    seq->mont_gap_av->fastdelay       = 250 ;
07983    seq->mont_gapcolor_av->fastdelay  = 250 ;
07984 
07985    seq->mont_nx_old       = seq->mont_nx       ; 
07986    seq->mont_ny_old       = seq->mont_ny       ;
07987    seq->mont_skip_old     = seq->mont_skip     ;
07988    seq->mont_gap_old      = seq->mont_gap      ;
07989    seq->mont_gapcolor_old = seq->mont_gapcolor ;
07990 
07991    MCW_reghelp_children( seq->mont_across_av->wrowcol ,
07992       "This controls the number\n"
07993       "of images displayed across\n"
07994       "(horizontally) the window."
07995    ) ;
07996    MCW_reghint_children( seq->mont_across_av->wrowcol ,
07997                          "Number of images horizontal" ) ;
07998 
07999    MCW_reghelp_children( seq->mont_down_av->wrowcol ,
08000       "This controls the number\n"
08001       "of images displayed down\n"
08002       "(vertically) the window."
08003    ) ;
08004    MCW_reghint_children( seq->mont_down_av->wrowcol ,
08005                          "Number of images vertical" ) ;
08006 
08007    MCW_reghelp_children( seq->mont_skip_av->wrowcol ,
08008       "This controls the spacing between\n"
08009       "slice images displayed in the\n"
08010       "montage.  For example, if Spacing\n"
08011       "is 4, every fourth slice will be\n"
08012       "displayed (from left to right, then\n"
08013       "top to bottom)."
08014    ) ;
08015    MCW_reghint_children( seq->mont_skip_av->wrowcol ,
08016                          "Spacing between images" ) ;
08017 
08018    MCW_reghelp_children( seq->mont_gap_av->wrowcol ,
08019       "This controls the number\n"
08020       "of pixels left as borders\n"
08021       "between the sub-images"
08022    ) ;
08023    MCW_reghint_children( seq->mont_gap_av->wrowcol ,
08024                          "Borders between images" ) ;
08025 
08026    MCW_reghelp_children( seq->mont_gapcolor_av->wrowcol ,
08027       "This controls the color\n"
08028       "put in the borders between\n"
08029       "the sub-images"
08030    ) ;
08031    MCW_reghint_children( seq->mont_gapcolor_av->wrowcol ,
08032                          "Border color" ) ;
08033 
08034    for( ib=0 ; ib < NUM_MONT_ACT ; ib++ )
08035       MONT_act[ib].data = (XtPointer) seq ;
08036 
08037    (void) MCW_action_area( wrc , MONT_act , NUM_MONT_ACT ) ;
08038 
08039    XtManageChild( wrc ) ;
08040    ISQ_place_dialog( seq ) ;  
08041    XtPopup( seq->dialog , XtGrabNone ) ;
08042    NORMAL_cursorize( seq->dialog ) ;
08043    ISQ_but_done_reset( seq ) ;
08044    EXRETURN ;
08045 }
08046 
08047 
08048 
08049 void ISQ_montage_action_CB( Widget w , XtPointer client_data , XtPointer call_data )
08050 {
08051    MCW_imseq * seq = (MCW_imseq *) client_data ;
08052    XmAnyCallbackStruct * cbs = (XmAnyCallbackStruct *) call_data ;
08053    char * wname ;
08054    int ib , close_window , new_mont ;
08055 
08056 ENTRY("ISQ_montage_action_CB") ;
08057 
08058    if( !ISQ_REALZ(seq) || seq->dialog==NULL || seq->dialog_starter!=NBUT_MONT ) EXRETURN ;
08059 
08060    wname = XtName(w) ;
08061 
08062    for( ib=0 ; ib < NUM_MONT_ACT ; ib++ )           
08063       if( strcmp(wname,MONT_act[ib].label) == 0 ) break ;
08064 
08065    close_window = (ib == MONT_DONE || ib == MONT_QUIT || ib == NUM_MONT_ACT) ;
08066 
08067    if( close_window ){
08068      RWC_XtPopdown( seq->dialog ) ;
08069      XSync( XtDisplay(w) , False ) ;
08070      XmUpdateDisplay( w ) ;
08071      seq->dont_place_dialog = 1 ;  
08072    }
08073 
08074    switch( ib ){
08075 
08076       case MONT_APPLY:
08077       case MONT_DONE:
08078          seq->mont_nx       = seq->mont_across_av->ival ;
08079          seq->mont_ny       = seq->mont_down_av->ival ;
08080          seq->mont_skip     = seq->mont_skip_av->ival - 1 ;
08081          seq->mont_gap      = seq->mont_gap_av->ival ;
08082          seq->mont_gapcolor = seq->mont_gapcolor_av->ival ;
08083 
08084          new_mont = ( seq->mont_nx   != seq->mont_nx_old ||
08085                       seq->mont_ny   != seq->mont_ny_old ||
08086                       seq->mont_skip != seq->mont_skip_old ) ;
08087 
08088          if( ib == MONT_APPLY ) MCW_invert_widget(w) ;
08089 
08090          ISQ_redisplay( seq , -1 , isqDR_display ) ;    
08091 
08092          if( seq->status->send_CB != NULL && new_mont ){
08093 
08094             ISQ_cbs cbs ;
08095             THD_ivec3 minf ;
08096             int ijcen = (seq->mont_nx)/2 + (seq->mont_ny/2) * seq->mont_nx ,
08097                 nmont = seq->mont_nx * seq->mont_ny ;
08098 
08099             minf.ijk[0]  = ijcen ;            
08100             minf.ijk[1]  = nmont-ijcen-1 ;    
08101             minf.ijk[2]  = seq->mont_skip ;   
08102             cbs.reason   = isqCR_newmontage ;
08103             cbs.userdata = (XtPointer) &minf ;
08104 
08105             seq->ignore_redraws = 1 ;         
08106 #if 0
08107             seq->status->send_CB( seq , seq->getaux , &cbs ) ;
08108 #else
08109             SEND(seq,cbs) ;
08110 #endif
08111             seq->ignore_redraws = 0 ;         
08112          }
08113 
08114 #if 0
08115          ISQ_redisplay( seq , -1 , isqDR_display ) ;    
08116 #endif
08117 
08118          if( ib == MONT_APPLY ) MCW_invert_widget(w) ;
08119 
08120          seq->mont_nx_old       = seq->mont_nx ;
08121          seq->mont_ny_old       = seq->mont_ny ;
08122          seq->mont_skip_old     = seq->mont_skip ;
08123          seq->mont_gap_old      = seq->mont_gap ;
08124          seq->mont_gapcolor_old = seq->mont_gapcolor ;
08125 
08126          
08127 
08128          if( seq->mont_nx * seq->mont_ny > 1 && !seq->opt.save_one ){
08129             seq->opt.save_one  = 1 ;
08130             seq->opt.save_agif = 0 ; 
08131             seq->opt.save_mpeg = 0 ;
08132             SET_SAVE_LABEL(seq) ;
08133          }
08134       break ;
08135 
08136       case MONT_1X1:
08137          MCW_invert_widget(w) ;
08138          AV_assign_ival( seq->mont_across_av , 1 ) ;
08139          AV_assign_ival( seq->mont_down_av   , 1 ) ;
08140          MCW_invert_widget(w) ;
08141       break ;
08142    }
08143 
08144    
08145 
08146    if( close_window ){                          
08147       XtDestroyWidget( seq->dialog ) ;
08148       seq->dialog = NULL ;
08149       for( ib=0 ; ib < NBUTTON_BOT-1 ; ib++ )       
08150          if( ISQ_but_bot_dial[ib] == True )         
08151             SENSITIZE( seq->wbut_bot[ib] , True ) ; 
08152 
08153       FREE_AV( seq->mont_across_av ) ;
08154       FREE_AV( seq->mont_down_av ) ;
08155       FREE_AV( seq->mont_skip_av ) ;
08156       FREE_AV( seq->mont_gap_av ) ;
08157       FREE_AV( seq->mont_gapcolor_av ) ;
08158 
08159       seq->mont_across_av   = NULL ;
08160       seq->mont_down_av     = NULL ;
08161       seq->mont_skip_av     = NULL ;
08162       seq->mont_gap_av      = NULL ;
08163       seq->mont_gapcolor_av = NULL ;
08164 
08165       seq->dialog_starter = -1 ;
08166       seq->dont_place_dialog = 0 ;  
08167    }
08168 
08169    EXRETURN ;
08170 }
08171 
08172 
08173 
08174 
08175 
08176 
08177 MRI_IMAGE * ISQ_manufacture_one( int nim , int overlay , MCW_imseq * seq )
08178 {
08179    MRI_IMAGE * im , * ovim , * tim ;
08180    int nrold ;
08181 
08182 ENTRY("ISQ_manufacture_one") ;
08183 
08184    if( ! ISQ_VALID(seq) ) RETURN( NULL );
08185 
08186    if( seq->mont_periodic ){
08187       while( nim < 0 )                       nim += seq->status->num_total ;
08188       while( nim >= seq->status->num_total ) nim -= seq->status->num_total ;
08189    } else {
08190       if( nim < 0 || nim >= seq->status->num_total ) RETURN( NULL );
08191    }
08192 
08193 
08194 
08195    if( ! overlay ){
08196       tim = ISQ_getimage( nim , seq ) ;
08197       if( tim == NULL ) RETURN( NULL );
08198       im = ISQ_process_mri( nim , seq , tim ) ; mri_free(tim) ;
08199       RETURN( im );
08200    }
08201 
08202 
08203 
08204    if( ISQ_SKIP_OVERLAY(seq) ) RETURN( NULL );
08205 
08206    tim = ISQ_getoverlay( nim , seq ) ;
08207 
08208    if( tim == NULL ) RETURN( NULL );
08209 
08210    if( !ISQ_GOOD_OVERLAY_TYPE(tim->kind) ){
08211       fprintf(stderr,"\a\n*** Illegal overlay image kind=%d! ***\n",tim->kind) ;
08212       mri_free(tim) ; RETURN( NULL );
08213    }
08214 
08215    ovim = mri_flippo( ISQ_TO_MRI_ROT(seq->opt.rot),seq->opt.mirror,tim ) ;
08216    if( tim != ovim ) mri_free(tim) ;
08217    RETURN( ovim );
08218 }
08219 
08220 
08221 
08222 
08223 
08224 
08225 void ISQ_make_montage( MCW_imseq *seq )
08226 {
08227    MRI_IMAGE *im , *ovim , *tim ;
08228    Boolean reset_done = False ;
08229    float fac , wmm , hmm ;
08230    short gap_ov ;
08231 
08232    byte  gap_rgb[3] ;  
08233    void  *gapval ;
08234    int   isrgb ;
08235    int   isrgb_ov ;    
08236 
08237 ENTRY("ISQ_make_montage");
08238 
08239    if( ! ISQ_VALID(seq) ) EXRETURN ;
08240 
08241    KILL_2XIM( seq->given_xim , seq->sized_xim ) ;  
08242 
08243    if( seq->mplot != NULL ){                           
08244      delete_memplot( seq->mplot ) ; seq->mplot = NULL ;
08245    }
08246 
08247    
08248 
08249    if( seq->opt.rot         != seq->old_opt.rot         ||
08250        seq->opt.mirror      != seq->old_opt.mirror      ||
08251        seq->opt.scale_group != seq->old_opt.scale_group ||
08252        seq->opt.scale_range != seq->old_opt.scale_range ||
08253        seq->mont_nx         != seq->mont_nx_old         ||
08254        seq->mont_ny         != seq->mont_ny_old         ||
08255        seq->mont_skip       != seq->mont_skip_old         ){
08256 
08257       KILL_1MRI( seq->imim ) ;  
08258       KILL_1MRI( seq->ovim ) ;
08259    }
08260 
08261    
08262 
08263    im = seq->imim ;
08264 
08265    if( im == NULL ){
08266       float new_width_mm = 0.0 , new_height_mm = 0.0 ;
08267       int   nxim = 0 , nyim = 0 , nxyim = 0 ;
08268       int ij , nim , nmont = seq->mont_nx * seq->mont_ny , ijcen ;
08269       MRI_IMARR * mar ;
08270 
08271       INIT_IMARR(mar) ;
08272 
08273 
08274 
08275 
08276 
08277 
08278 
08279       isrgb = 0 ;
08280       ijcen = (seq->mont_nx)/2 + (seq->mont_ny/2) * seq->mont_nx ;
08281       for( ij=0 ; ij < nmont ; ij++ ){
08282          nim = seq->im_nr + (seq->mont_skip + 1)* (ij - ijcen) ;
08283 
08284 DPRI(" Getting montage underlay",nim) ;
08285 
08286          seq->set_orim = (seq->need_orim != 0 && nim == seq->im_nr) ;  
08287          tim = ISQ_manufacture_one( nim , 0 , seq ) ;
08288          seq->set_orim = 0 ;                                           
08289          ADDTO_IMARR(mar,tim) ;
08290 
08291          if( nim == seq->im_nr ){
08292             new_width_mm  = IM_WIDTH(tim)  ; nxim = tim->nx ;
08293             new_height_mm = IM_HEIGHT(tim) ; nyim = tim->ny ;
08294             seq->last_image_type = tim->kind ;
08295             seq->barbot = seq->clbot ; 
08296             seq->bartop = seq->cltop ;
08297             ISQ_set_barhint(seq,"Focus") ;
08298             seq->last_dx = fabs(tim->dx) ; seq->last_dy = fabs(tim->dy) ;
08299          }
08300 
08301          if( tim != NULL ){
08302             isrgb = isrgb || (tim != NULL && tim->kind == MRI_rgb) ;
08303             nxyim++ ;
08304          }
08305       }
08306 
08307       if( nxyim == 0 ){                                        
08308          fprintf(stderr,"** Montage error: no images found!\n") ;
08309          DESTROY_IMARR(mar) ; EXRETURN ;
08310       }
08311 
08312 DPRI(" Making underlay cat2D from",nxyim) ;
08313 
08314       if( isrgb ){                       
08315          if( seq->mont_gapcolor > 0 )
08316             DC_pixel_to_rgb( seq->dc , seq->dc->ovc->pix_ov[seq->mont_gapcolor],
08317                              gap_rgb , gap_rgb+1 , gap_rgb+2 ) ;
08318          else
08319             gap_rgb[0] = gap_rgb[1] = gap_rgb[2] = 0 ;
08320 
08321          gapval = (void *) gap_rgb ;
08322       } else {
08323          gap_ov = -(seq->mont_gapcolor) ;  
08324          gapval = (void *) &gap_ov ;
08325       }
08326 
08327       
08328 
08329       if( isrgb ){
08330          for( ij=0 ; ij < nmont ; ij++ ){
08331             tim = IMARR_SUBIMAGE(mar,ij) ;
08332             if( tim != NULL && tim->kind != MRI_rgb ){
08333                MRI_IMAGE * qim ;
08334 
08335                if( tim->kind == MRI_short )
08336                   qim = ISQ_index_to_rgb( seq->dc , 0 , tim ) ; 
08337                else
08338                   qim = mri_to_rgb( tim ) ;                     
08339 
08340                mri_free(tim) ;                   
08341                IMARR_SUBIMAGE(mar,ij) = qim ;
08342             }
08343          }
08344       }
08345 
08346       
08347 
08348       seq->imim = im = mri_cat2D( seq->mont_nx , seq->mont_ny ,     
08349                                   seq->mont_gap , gapval , mar ) ;  
08350 
08351 DPR("Destroying underlay image array") ;
08352 
08353       DESTROY_IMARR(mar) ;
08354 
08355       
08356 
08357       seq->horig = nxim ; seq->vorig = nyim ;
08358 
08359       wmm = ( nxim*seq->mont_nx + seq->mont_gap*(seq->mont_nx-1) )
08360            / (float) nxim ;
08361 
08362       hmm = ( nyim*seq->mont_ny + seq->mont_gap*(seq->mont_ny-1) )
08363            / (float) nyim ;
08364 
08365       fac = sqrt( wmm / hmm ) ;
08366 
08367       new_width_mm  *= fac ;
08368       new_height_mm /= fac ;
08369 
08370       if( FLDIF(new_width_mm ,seq->last_width_mm ) ||
08371           FLDIF(new_height_mm,seq->last_height_mm)   ){
08372 
08373          ISQ_reset_dimen( seq , new_width_mm , new_height_mm ) ;
08374          reset_done = True ;
08375       }
08376    }
08377 
08378 
08379 
08380    if( seq->opt.free_aspect != seq->old_opt.free_aspect && !reset_done )
08381       ISQ_reset_dimen( seq , seq->last_width_mm , seq->last_height_mm ) ;
08382 
08383    
08384 
08385    if( ISQ_SKIP_OVERLAY(seq) ){
08386       KILL_1MRI( seq->ovim ) ; ovim = NULL ;  
08387    } else {
08388       int ij , nim , nmont=seq->mont_nx * seq->mont_ny , nov=0 , ijcen ;
08389 
08390       MEM_plotdata *mp ; 
08391       int ii,jj ;
08392       float sx,sy,st , xb,xt,yb,yt , tx,ty ;
08393 
08394       ijcen = (seq->mont_nx)/2 + (seq->mont_ny/2) * seq->mont_nx ;
08395 
08396       
08397 
08398       ovim = seq->ovim ;
08399       if( ovim == NULL ){
08400          MRI_IMARR * mar ;
08401 
08402          INIT_IMARR(mar) ;
08403 
08404          isrgb_ov = 0 ;  
08405 
08406          for( ij=0 ; ij < nmont ; ij++ ){
08407             nim = seq->im_nr + (seq->mont_skip + 1) * (ij - ijcen) ;
08408 
08409 DPRI(" Getting montage overlay",nim) ;
08410 
08411             tim = ISQ_manufacture_one( nim , 1 , seq ) ;
08412             ADDTO_IMARR(mar,tim) ;
08413             if( tim != NULL ){
08414                nov++ ; isrgb_ov = isrgb_ov || tim->kind == MRI_rgb ;
08415             }
08416          }
08417 
08418 DPRI(" Making overlay cat2D from",nov) ;
08419 
08420          
08421 
08422          if( isrgb_ov ){
08423             for( ij=0 ; ij < nmont ; ij++ ){
08424                tim = IMARR_SUBIMAGE(mar,ij) ;
08425                if( tim != NULL && tim->kind != MRI_rgb ){
08426                   MRI_IMAGE * qim ;
08427 
08428                   if( tim->kind == MRI_short )
08429                      qim = ISQ_index_to_rgb( seq->dc , 1 , tim ) ; 
08430                   else
08431                      qim = mri_to_rgb( tim ) ;                     
08432 
08433                   mri_free(tim) ;                   
08434                   IMARR_SUBIMAGE(mar,ij) = qim ;
08435                }
08436             }
08437          }
08438 
08439          if( isrgb_ov ){
08440             gap_rgb[0] = gap_rgb[1] = gap_rgb[2] = 0 ;
08441             gapval = (void *) gap_rgb ;
08442          } else {
08443             gap_ov = 0 ;
08444             gapval = (void *) &gap_ov ;
08445          }
08446 
08447          if( nov > 0 ){
08448             ovim = seq->ovim =                                
08449                mri_cat2D( seq->mont_nx , seq->mont_ny ,       
08450                           seq->mont_gap , gapval ,  mar ) ;
08451          } else
08452             ovim = seq->ovim = NULL ;                         
08453 
08454 DPR("Destroying overlay image array") ;
08455 
08456          DESTROY_IMARR( mar ) ;
08457       }
08458 
08459       
08460 
08461       
08462 
08463 
08464       if( MCW_val_bbox(seq->wbar_plots_bbox) != 0 ){
08465        for( ij=0 ; ij < nmont ; ij++ ){
08466 
08467          nim = seq->im_nr + (seq->mont_skip + 1) * (ij - ijcen) ;
08468          if( seq->mont_periodic ){
08469             while( nim < 0 )                       nim += seq->status->num_total ;
08470             while( nim >= seq->status->num_total ) nim -= seq->status->num_total ;
08471          } else {
08472             if( nim < 0 || nim >= seq->status->num_total ) continue ; 
08473          }
08474 
08475          mp = ISQ_getmemplot( nim , seq ) ;
08476 
08477          if( mp == NULL ) continue ; 
08478 
08479          ii = ij % seq->mont_nx ;  
08480          jj = ij / seq->mont_nx ;  
08481 
08482          tx = im->nx ; ty = im->ny ;  
08483 
08484          
08485 
08486 
08487 
08488          xb = (seq->horig + seq->mont_gap) * ii ;
08489          xt = xb + seq->horig ;
08490          yb = (seq->vorig + seq->mont_gap) * (seq->mont_ny - 1 - jj) ;
08491          yt = yb + seq->vorig ;
08492 
08493          
08494 
08495 
08496          sx = (xt-xb) / tx ; tx = xb / tx ;
08497          sy = (yt-yb) / ty ; ty = yb / ty ;  st = sqrt(sx*sy) ;
08498 
08499          
08500 
08501          flip_memplot( ISQ_TO_MRI_ROT(seq->opt.rot),seq->opt.mirror, mp ) ;
08502 
08503          
08504 
08505          scale_memplot( sx,tx , sy,ty , st , mp ) ;
08506 
08507          
08508 
08509          if( seq->mplot == NULL ){  
08510            seq->mplot = mp ;
08511          } else {                  
08512            append_to_memplot( seq->mplot , mp ) ;
08513            delete_memplot( mp ) ;
08514          }
08515 
08516        } 
08517       } 
08518 
08519       
08520 
08521       if( seq->wbar_label_av->ival != 0 ){
08522        char *lab ;
08523 
08524        for( ij=0 ; ij < nmont ; ij++ ){
08525 
08526          nim = seq->im_nr + (seq->mont_skip + 1) * (ij - ijcen) ;
08527          if( seq->mont_periodic ){
08528             while( nim < 0 )                       nim += seq->status->num_total ;
08529             while( nim >= seq->status->num_total ) nim -= seq->status->num_total ;
08530          } else {
08531             if( nim < 0 || nim >= seq->status->num_total ) continue ; 
08532          }
08533 
08534          
08535 
08536          lab = ISQ_getlabel( nim , seq ) ;
08537          if( lab != NULL ){
08538           mp = ISQ_plot_label( seq , lab ) ;  
08539           if( mp != NULL ){
08540            ii = ij % seq->mont_nx ;  
08541            jj = ij / seq->mont_nx ;  
08542            tx = im->nx ; ty = im->ny ;  
08543            xb = (seq->horig + seq->mont_gap) * ii ;
08544            xt = xb + seq->horig ;
08545            yb = (seq->vorig + seq->mont_gap) * (seq->mont_ny - 1 - jj) ;
08546            yt = yb + seq->vorig ;
08547            sx = (xt-xb) / tx ; tx = xb / tx ;
08548            sy = (yt-yb) / ty ; ty = yb / ty ;  st = sqrt(sx*sy) ;
08549            scale_memplot( sx,tx , sy,ty , st , mp ) ;
08550            if( seq->mplot != NULL ){
08551              append_to_memplot( seq->mplot , mp ) ; delete_memplot( mp ) ;
08552            } else {
08553              seq->mplot = mp ;
08554            }
08555           }
08556           free(lab) ;
08557          }
08558        } 
08559       } 
08560 
08561    } 
08562 
08563    
08564 
08565    seq->old_opt = seq->opt ;
08566 
08567    seq->mont_nx_old        = seq->mont_nx        ;
08568    seq->mont_ny_old        = seq->mont_ny        ;
08569    seq->mont_skip_old      = seq->mont_skip      ;
08570    seq->mont_gap_old       = seq->mont_gap       ;
08571    seq->mont_gapcolor_old  = seq->mont_gapcolor  ;
08572 
08573    
08574 
08575    if( ovim == NULL || ISQ_SKIP_OVERLAY(seq) ){   
08576       tim = im ;
08577 
08578 #if 1                                  
08579    } else {
08580 
08581       tim = ISQ_overlay( seq->dc, im, ovim, seq->ov_opacity ) ;
08582       if( tim == NULL ) tim = im ;     
08583 
08584 #else                                  
08585    } else if( im->kind == MRI_short ){            
08586 
08587       register short * tar , * oar , * iar ;
08588       register int ii , npix = im->nx * im->ny ;
08589 
08590       tim = mri_new( im->nx , im->ny , MRI_short ) ;
08591       tar = MRI_SHORT_PTR( tim ) ;
08592       oar = MRI_SHORT_PTR( ovim ) ;
08593       iar = MRI_SHORT_PTR( im ) ;
08594       (void) memcpy( tar , iar , sizeof(short)*npix ) ; 
08595       for( ii=0 ; ii < npix ; ii++ )                    
08596          if( oar[ii] > 0 ) tar[ii] = -oar[ii] ;         
08597 
08598    } else if( im->kind == MRI_rgb ){                       
08599 
08600       register int ii , npix = im->nx * im->ny ;
08601       register short * oar = MRI_SHORT_PTR(ovim) ;
08602       register byte * tar , * iar = MRI_RGB_PTR(im) ;
08603       register Pixel * negpix = seq->dc->ovc->pix_ov ;
08604 
08605       tim = mri_to_rgb( im ) ; tar = MRI_RGB_PTR(tim) ;
08606 
08607       for( ii=0 ; ii < npix ; ii++ )
08608          if( oar[ii] > 0 )
08609             DC_pixel_to_rgb( seq->dc, negpix[oar[ii]], tar+(3*ii),tar+(3*ii+1),tar+(3*ii+2) ) ;
08610 #endif
08611    }
08612 
08613    
08614 
08615    seq->given_xim = mri_to_XImage( seq->dc , tim ) ;
08616 
08617    if( tim != im ) KILL_1MRI(tim) ;
08618    EXRETURN ;
08619 }
08620 
08621 
08622 
08623 
08624 
08625 
08626 
08627 
08628 
08629 
08630 
08631 
08632 void ISQ_mapxy( MCW_imseq * seq, int xwin, int ywin,
08633                 int * xim, int * yim, int * nim )
08634 {
08635    int win_wide,win_high , nxim,nyim ;
08636    int monx,mony,monsk,mongap , win_wide_orig,win_high_orig ;
08637    int xorg , yorg , ijcen , xcol,yrow , ij ;
08638    int zlev = seq->zoom_fac ;
08639 
08640 ENTRY("ISQ_mapxy") ;
08641 
08642    if( ! ISQ_REALZ(seq) ) EXRETURN ;
08643 
08644    nxim  = seq->horig     ; nyim   = seq->vorig    ;  
08645    monx  = seq->mont_nx   ; mony   = seq->mont_ny  ;  
08646    monsk = seq->mont_skip ; mongap = seq->mont_gap ;
08647 
08648    win_wide_orig = nxim * monx + mongap * (monx-1) ;  
08649    win_high_orig = nyim * mony + mongap * (mony-1) ;  
08650 
08651    
08652 
08653    if( seq->wimage_width <= 0 ){
08654       MCW_widget_geom( seq->wimage , &win_wide , &win_high , NULL,NULL ) ;
08655       seq->wimage_width  = win_wide ;
08656       seq->wimage_height = win_high ;
08657    } else {
08658       win_wide = seq->wimage_width ;
08659       win_high = seq->wimage_height ;
08660    }
08661 
08662    
08663 
08664 
08665 #if 0   
08666    xorg = ( (float) xwin / win_wide ) * win_wide_orig  ;
08667    yorg = ( (float) ywin / win_high ) * win_high_orig  ;
08668 #else
08669 
08670    
08671 
08672    if( zlev == 1 || monx > 1 || mony > 1 ){
08673 
08674      xorg = ( (float) xwin / win_wide ) * win_wide_orig  ;
08675      yorg = ( (float) ywin / win_high ) * win_high_orig  ;
08676 
08677    } else {  
08678 
08679      int pw=seq->zoom_pw , ph=seq->zoom_ph ;
08680      float xoff,yoff ;
08681 
08682      xoff = seq->zoom_hor_off*pw; if( xoff+win_wide > pw ) xoff = pw-win_wide;
08683      yoff = seq->zoom_ver_off*ph; if( yoff+win_high > ph ) yoff = ph-win_high;
08684 
08685      xorg = nxim * (xoff+xwin) / pw ;
08686      yorg = nyim * (yoff+ywin) / ph ;
08687    }
08688 #endif
08689 
08690    
08691 
08692 
08693    *xim = xorg % (nxim+mongap) ; xcol = xorg / (nxim+mongap) ;
08694    *yim = yorg % (nyim+mongap) ; yrow = yorg / (nyim+mongap) ;
08695 
08696    
08697 
08698 
08699    ij    = xcol   + yrow     * monx ;
08700    ijcen = monx/2 + (mony/2) * monx ;
08701    *nim  = seq->im_nr + (monsk+1) * (ij-ijcen) ;
08702 
08703    if( seq->mont_periodic ){
08704       while( *nim < 0 )                       *nim += seq->status->num_total ;
08705       while( *nim >= seq->status->num_total ) *nim -= seq->status->num_total ;
08706    }
08707 
08708    
08709 
08710 
08711    ISQ_flipxy( seq , xim , yim ) ;
08712 
08713    if( seq->cropit ){       
08714      *xim += seq->crop_xa ;
08715      *yim += seq->crop_ya ;
08716    }
08717 
08718    EXRETURN ;
08719 }
08720 
08721 
08722 
08723 
08724 
08725 
08726 
08727 
08728 
08729 void ISQ_flipxy( MCW_imseq * seq, int * xflip, int * yflip )
08730 {
08731    int fopt , xim , yim , nx,ny ;
08732 
08733 ENTRY("ISQ_flipxy") ;
08734 
08735    fopt = ISQ_TO_MRI_ROT(seq->opt.rot) ;
08736    if( seq->opt.mirror ) fopt += MRI_FLMADD ;
08737 
08738    nx = seq->horig ; ny = seq->vorig ;
08739 
08740    switch( fopt ){
08741 
08742       default:                                    
08743       case (MRI_ROT_0):
08744          xim = *xflip ; yim = *yflip ; break ;
08745 
08746       case (MRI_ROT_90):                          
08747          xim = ny-1-*yflip ; yim = *xflip ; break ;
08748 
08749       case (MRI_ROT_180):                         
08750          xim = nx-1-*xflip ; yim = ny-1-*yflip ; break ;
08751 
08752       case (MRI_ROT_270):                         
08753          xim = *yflip ; yim = nx-1-*xflip ; break ;
08754 
08755       case (MRI_ROT_0+MRI_FLMADD):                
08756          xim = nx-1-*xflip ; yim = *yflip ; break ;
08757 
08758       case (MRI_ROT_90+MRI_FLMADD):               
08759          xim = ny-1-*yflip ; yim = nx-1-*xflip ; break ;
08760 
08761       case (MRI_ROT_180+MRI_FLMADD):              
08762          xim = *xflip ; yim = ny-1-*yflip ; break ;
08763 
08764       case (MRI_ROT_270+MRI_FLMADD):              
08765          xim = *yflip ; yim = *xflip ; break ;
08766    }
08767 
08768    *xflip = xim ; *yflip = yim ; EXRETURN ;
08769 }
08770 
08771 
08772 
08773 void ISQ_unflipxy( MCW_imseq * seq, int * xflip, int * yflip )
08774 {
08775    int fopt , xim , yim , nx,ny ;
08776 
08777 ENTRY("ISQ_unflipxy") ;
08778 
08779    fopt = ISQ_TO_MRI_ROT(seq->opt.rot) ;
08780    if( seq->opt.mirror ) fopt += MRI_FLMADD ;
08781 
08782    nx = seq->horig ; ny = seq->vorig ;
08783 
08784    switch( fopt ){
08785 
08786       default:                                    
08787       case (MRI_ROT_0):
08788          xim = *xflip ; yim = *yflip ; break ;
08789 
08790       case (MRI_ROT_90):                          
08791          yim = ny-1-*xflip ; xim = *yflip ; break ;
08792 
08793       case (MRI_ROT_180):                         
08794          xim = nx-1-*xflip ; yim = ny-1-*yflip ; break ;
08795 
08796       case (MRI_ROT_270):                         
08797          yim = *xflip ; xim = nx-1-*yflip ; break ;
08798 
08799       case (MRI_ROT_0+MRI_FLMADD):                
08800          xim = nx-1-*xflip ; yim = *yflip ; break ;
08801 
08802       case (MRI_ROT_90+MRI_FLMADD):               
08803          yim = ny-1-*xflip ; xim = nx-1-*yflip ; break ;
08804 
08805       case (MRI_ROT_180+MRI_FLMADD):              
08806          xim = *xflip ; yim = ny-1-*yflip ; break ;
08807 
08808       case (MRI_ROT_270+MRI_FLMADD):              
08809          xim = *yflip ; yim = *xflip ; break ;
08810    }
08811 
08812    *xflip = xim ; *yflip = yim ; EXRETURN ;
08813 }
08814 
08815 
08816 
08817 
08818 
08819 char * ISQ_transform_label( MCW_arrowval * av , XtPointer cd )
08820 {
08821    MCW_function_list * xforms = (MCW_function_list *) cd ;
08822 
08823    if( av == NULL    || xforms == NULL        ||
08824        av->ival <= 0 || av->ival > xforms->num  ) return "-none-" ;
08825 
08826    return xforms->labels[av->ival - 1] ;  
08827 }
08828 
08829 
08830 
08831 void ISQ_transform_CB( MCW_arrowval * av , XtPointer cd )
08832 {
08833    MCW_imseq * seq = (MCW_imseq *) cd ;
08834 
08835 ENTRY("ISQ_transform_CB") ;
08836 
08837    if( ! ISQ_VALID(seq) ) EXRETURN ;
08838 
08839 
08840 
08841    if( av != NULL && av == seq->transform0D_av ){
08842       if( seq->status->transforms0D == NULL || av->ival <= 0 ||
08843           av->ival > seq->status->transforms0D->num            ){
08844 
08845          seq->transform0D_func  = NULL ;  
08846          seq->transform0D_index = 0 ;
08847       } else {
08848          seq->transform0D_func  = seq->status->transforms0D->funcs[av->ival - 1] ;
08849          seq->transform0D_index = av->ival ;
08850 
08851          
08852 
08853          if( seq->status->transforms0D->func_init[av->ival-1] != NULL )
08854           seq->status->transforms0D->func_init[av->ival-1]() ;
08855 
08856       }
08857    }
08858 
08859 
08860 
08861    if( av != NULL && av == seq->transform2D_av ){
08862       if( seq->status->transforms2D == NULL || av->ival <= 0 ||
08863           av->ival > seq->status->transforms2D->num            ){
08864 
08865          seq->transform2D_func  = NULL ;  
08866          seq->transform2D_index = 0 ;
08867       } else {
08868          seq->transform2D_func  = seq->status->transforms2D->funcs[av->ival - 1] ;
08869          seq->transform2D_index = av->ival ;
08870 
08871          
08872 
08873          if( seq->status->transforms2D->func_init[av->ival-1] != NULL )
08874           seq->status->transforms2D->func_init[av->ival-1]() ;
08875       }
08876    }
08877 
08878    ISQ_redisplay( seq , -1 , isqDR_reimage ) ;  
08879    EXRETURN ;
08880 }
08881 
08882 
08883 
08884 void ISQ_slice_proj_CB( MCW_arrowval * av , XtPointer cd )
08885 {
08886    MCW_imseq * seq = (MCW_imseq *) cd ;
08887 
08888 ENTRY("ISQ_slice_proj_CB") ;
08889 
08890    if( ! ISQ_VALID(seq) ) EXRETURN ;
08891 
08892 
08893 
08894    if( av != NULL && av == seq->slice_proj_av ){
08895       if( seq->status->slice_proj == NULL || av->ival <= 0 ||
08896           av->ival > seq->status->slice_proj->num            ){
08897 
08898          seq->slice_proj_func  = NULL ;  
08899          seq->slice_proj_index = 0 ;
08900       } else {
08901          seq->slice_proj_func  = (float_func *)
08902                                  seq->status->slice_proj->funcs[av->ival - 1] ;
08903          seq->slice_proj_index = av->ival ;
08904       }
08905    }
08906 
08907    seq->slice_proj_range = seq->slice_proj_range_av->ival ;
08908 
08909    ISQ_redisplay( seq , -1 , isqDR_reimage ) ;  
08910    EXRETURN ;
08911 }
08912 
08913 
08914 
08915 
08916 
08917 char * ISQ_rowgraph_label( MCW_arrowval * av , XtPointer cd )
08918 {
08919    static char buf[16] ;
08920    sprintf(buf,"%2d  ",av->ival) ;
08921    return buf ;
08922 }
08923 
08924 void ISQ_rowgraph_CB( MCW_arrowval * av , XtPointer cd )
08925 {
08926    MCW_imseq * seq = (MCW_imseq *) cd ;
08927 
08928 ENTRY("ISQ_rowgraph_CB") ;
08929 
08930    if( ! ISQ_VALID(seq) ) EXRETURN ;               
08931    if( av->ival == seq->rowgraph_num ) EXRETURN ;  
08932 
08933    seq->rowgraph_num = av->ival ;
08934 
08935    if( seq->rowgraph_num > 0 ) seq->need_orim |=  ROWGRAPH_MASK ;
08936    else                        seq->need_orim &= ~ROWGRAPH_MASK ;
08937    if( seq->need_orim == 0 ) KILL_1MRI(seq->orim) ;
08938 
08939    ISQ_redisplay( seq , -1 , isqDR_reimage ) ;  
08940    EXRETURN ;
08941 }
08942 
08943 void ISQ_rowgraph_draw( MCW_imseq *seq )
08944 {
08945    MEM_plotdata *mp ;
08946    ISQ_cbs cbs ;
08947    int jbot,ix,jy , nrow , jj , nx,ny , ymask ;
08948    float *yar[ROWGRAPH_MAX] ;
08949 
08950 ENTRY("ISQ_rowgraph_draw") ;
08951 
08952    if( ! ISQ_REALZ(seq) ) EXRETURN ;  
08953 
08954    
08955 
08956    if( seq->rowgraph_num == 0 ){
08957      if( seq->rowgraph_mtd != NULL ){
08958        plotkill_topshell( seq->rowgraph_mtd ) ;
08959        seq->rowgraph_mtd = NULL ;
08960      }
08961      EXRETURN ;
08962    }
08963 
08964    if( seq->orim == NULL ) EXRETURN ;
08965 
08966    
08967 
08968    cbs.reason = isqCR_getxynim ;
08969    cbs.xim = cbs.yim = cbs.nim = -666 ;
08970    if( seq->status->send_CB != NULL )
08971 #if 0
08972      seq->status->send_CB( seq , seq->getaux , &cbs ) ;
08973 #else
08974      SEND(seq,cbs) ;
08975 #endif
08976    if( cbs.xim < 0 || cbs.yim < 0 ){
08977      fprintf(stderr,
08978       "*** error in ISQ_rowgraph_draw: xim=%d yim=%d\n",cbs.xim,cbs.yim) ;
08979      EXRETURN ;  
08980    }
08981    ISQ_unflipxy( seq , &(cbs.xim) , &(cbs.yim) ) ;
08982    jy = jbot = cbs.yim ; ix = cbs.xim ;
08983 
08984    
08985 
08986    if( jbot < 0 || jbot >= seq->orim->ny ){
08987       fprintf(stderr,"*** error in ISQ_rowgraph_draw: jbot=%d\n",jbot) ;
08988       EXRETURN ;  
08989    }
08990 
08991    nrow = MIN( seq->rowgraph_num  , jbot+1 ) ;
08992    nx   = seq->orim->nx ;
08993    ny   = seq->orim->ny ;
08994 
08995    for( jj=0 ; jj < nrow ; jj++ )
08996      yar[jj] = MRI_FLOAT_PTR(seq->orim) + (jbot-jj)*nx ;
08997 
08998    
08999 
09000    ymask = TSP_SEPARATE_YBOX ;
09001 
09002    mp = plot_ts_mem( nx , NULL , nrow,ymask,yar , "Column (pixels)",NULL,NULL,NULL ) ;
09003    if( mp == NULL ){
09004       fprintf(stderr,"*** error in ISQ_rowgraph_draw: can't make plot_ts_mem\n") ;
09005       EXRETURN ;  
09006    }
09007 
09008    
09009 
09010    if( !ISQ_SKIP_OVERLAY(seq) && ix >= 0 && ix < nx && jy >= 0 && jy < ny ){
09011       float xx , yy , dx , dy , xbot,xtop, ybot,ytop ;
09012 
09013       xx = ix ; dx = 0.016 * nx ; yy = yar[0][ix] ;
09014 #if 0
09015       ybot = ytop = yar[0][0] ;
09016       for( jj=1 ; jj < nx ; jj++ )
09017               if( yar[0][jj] < ybot ) ybot = yar[0][jj] ;
09018          else if( yar[0][jj] > ytop ) ytop = yar[0][jj] ;
09019       dy = 0.016 * nrow * (ytop-ybot) ;
09020 #else
09021       plotpak_getset( NULL,NULL,NULL,NULL , &xbot,&xtop , &ybot,&ytop ) ;
09022       dx = 0.016 * fabs(xtop-xbot) ;
09023       dy = 0.016 * fabs(ytop-ybot) * nrow ;
09024 #endif
09025 
09026 #undef  THIK
09027 #define THIK 0.003
09028 
09029       set_color_memplot( 0.8 , 0.0 , 0.2 ) ;
09030       set_thick_memplot( THIK ) ;
09031       plotpak_line( xx-dx , yy    , xx+dx , yy    ) ; 
09032       plotpak_line( xx    , yy-dy , xx    , yy+dy ) ; 
09033       plotpak_line( xx-dx , yy-dy , xx+dx , yy+dy ) ; 
09034       plotpak_line( xx+dx , yy-dy , xx-dx , yy+dy ) ; 
09035       set_color_memplot( 0.2 , 0.0 , 0.8 ) ;
09036       plotpak_line( xx+dx , yy-dy , xx+dx , yy+dy ) ; 
09037       plotpak_line( xx+dx , yy+dy , xx-dx , yy+dy ) ;
09038       plotpak_line( xx-dx , yy+dy , xx-dx , yy-dy ) ;
09039       plotpak_line( xx-dx , yy-dy , xx+dx , yy-dy ) ;
09040       set_color_memplot( 0.0 , 0.0 , 0.0 ) ;
09041       set_thick_memplot( 0.0 ) ;
09042    }
09043 
09044    
09045 
09046    if( seq->rowgraph_mtd != NULL ){
09047 
09048       MTD_replace_plotdata( seq->rowgraph_mtd , mp ) ;
09049       redraw_topshell( seq->rowgraph_mtd ) ;
09050 
09051    } else {  
09052 
09053       seq->rowgraph_mtd = memplot_to_topshell( seq->dc->display, mp, ISQ_rowgraph_mtdkill ) ;
09054 
09055       if( seq->rowgraph_mtd == NULL ){ delete_memplot( mp ); EXRETURN; }
09056 
09057       seq->rowgraph_mtd->userdata = (void *) seq ;
09058    }
09059 
09060    EXRETURN ;
09061 }
09062 
09063 
09064 
09065 
09066 void ISQ_rowgraph_mtdkill( MEM_topshell_data * mp )
09067 {
09068    MCW_imseq * seq ;
09069 
09070 ENTRY("ISQ_rowgraph_mtdkill") ;
09071 
09072    if( mp == NULL ) EXRETURN ;
09073    seq = (MCW_imseq *) mp->userdata ; if( ! ISQ_VALID(seq) ) EXRETURN ;
09074 
09075    seq->rowgraph_mtd = NULL ;
09076 
09077    AV_assign_ival( seq->rowgraph_av , 0 ) ;
09078    seq->rowgraph_num = 0 ;
09079    EXRETURN ;
09080 }
09081 
09082 
09083 
09084 
09085 void ISQ_graymap_mtdkill( MEM_topshell_data *mp )  
09086 {
09087    MCW_imseq *seq ;
09088 
09089 ENTRY("ISQ_graymap_mtdkill") ;
09090 
09091    if( mp == NULL ) EXRETURN ;
09092    seq = (MCW_imseq *) mp->userdata ;
09093    if( ISQ_VALID(seq) ){
09094      seq->graymap_mtd = NULL ;
09095      seq->need_orim &= ~GRAYMAP_MASK ;  
09096    }
09097 
09098    EXRETURN ;
09099 }
09100 
09101 
09102 
09103 void ISQ_graymap_draw( MCW_imseq *seq )  
09104 {
09105    MEM_plotdata *mp ;
09106    int ix , nx , ny , nxx ;
09107    float *yar[2] , *xar , dx , *ar ;
09108 
09109 ENTRY("ISQ_graymap_draw") ;
09110 
09111    if( !ISQ_REALZ(seq) || seq->dc->use_xcol_im ) EXRETURN ;  
09112 
09113    seq->need_orim |= GRAYMAP_MASK ;
09114 
09115    
09116    
09117 
09118    nx     = seq->dc->ncol_im ;
09119    nxx    = 2*nx+2 ;
09120    ny     = 1 ;
09121    dx     = (seq->bartop - seq->barbot) / nx ; if( dx == 0.0 ) EXRETURN ;
09122    yar[0] = (float *) malloc( sizeof(float)*nxx ) ;
09123    xar    = (float *) malloc( sizeof(float)*nxx ) ;
09124    xar[0] = seq->barbot ;
09125    for( ix=0 ; ix < nx ; ix++ ){
09126      xar[2*ix+1]     = seq->barbot + ix*dx ;
09127      xar[2*ix+2]     = seq->barbot + (ix+1)*dx ;
09128      yar[0][2*ix+1]  = seq->dc->xint_im[ix] ;
09129      if( yar[0][2*ix+1] < 0.0 ){
09130        yar[0][2*ix+1] = 0.0 ;
09131      } else {
09132        yar[0][2*ix+1] *= (255.0/65280.0);
09133        if( yar[0][2*ix+1] > 255.0 ) yar[0][2*ix+1] = 255.0;
09134      }
09135      yar[0][2*ix+2] = yar[0][2*ix+1] ;
09136    }
09137    xar[2*nx+1]    = seq->bartop ;
09138    yar[0][0]      = yar[0][1] ;
09139    yar[0][2*nx+1] = yar[0][2*nx] ;
09140 
09141    
09142 
09143    if( seq->orim != NULL ){
09144      float *iar=MRI_FLOAT_PTR(seq->orim) , *har , val ;
09145      float scl=nx/(seq->bartop-seq->barbot) ; int ii,jj ;
09146      har = (float *) calloc( sizeof(float),nx  ) ;
09147      for( ii=0 ; ii < seq->orim->nvox ; ii++ ){
09148        jj = (int)( scl*(iar[ii]-seq->barbot) ) ;
09149        if( jj < 0 ) jj = 0 ; else if( jj > nx-1 ) jj = nx-1 ;
09150        har[jj] += 1.0 ;
09151      }
09152      for( scl=0.0,ii=1 ; ii < nx ; ii++ )
09153        if( har[ii] > scl ) scl = har[ii] ;
09154      if( scl > 0.0 ){
09155        ny = 2 ;
09156        yar[1] = (float *) malloc( sizeof(float)*nxx ) ;
09157        scl = 255.0/sqrt(scl) ;
09158        yar[1][0] = yar[1][2*nx+1] = 0.0 ;
09159        for( ii=0 ; ii < nx ; ii++ ){
09160          val = scl*sqrt(har[ii]) ; if( val > 255.0 ) val = 255.0 ;
09161          yar[1][2*ii+1] = yar[1][2*ii+2] = val ;
09162        }
09163      }
09164      free( (void *)har ) ;
09165    }
09166 
09167    
09168 
09169    mp = plot_ts_mem( nxx,xar, ny,0,yar, "Data Value",
09170                      (ny == 1) ? "GrayLevel"
09171                                : "GrayLevel\\red/Histogram\\black" ,
09172                      NULL,NULL ) ;
09173    free(xar); free(yar[0]); if( ny == 2 ) free(yar[1]) ;
09174    if( mp == NULL ){
09175      fprintf(stderr,"*** error in ISQ_graymap_draw: can't make plot_ts_mem\n") ;
09176      EXRETURN ;  
09177    }
09178 
09179    
09180 
09181    if( seq->graymap_mtd != NULL ){
09182 
09183       MTD_replace_plotdata( seq->graymap_mtd , mp ) ;
09184       redraw_topshell( seq->graymap_mtd ) ;
09185 
09186    } else {  
09187 
09188       seq->graymap_mtd = memplot_to_topshell( seq->dc->display, mp, ISQ_graymap_mtdkill ) ;
09189       if( seq->graymap_mtd == NULL ){ delete_memplot(mp); EXRETURN; }
09190       seq->graymap_mtd->userdata = (void *) seq ;
09191       ISQ_place_widget( seq->wtop , seq->graymap_mtd->top ) ;
09192    }
09193 
09194    EXRETURN ;
09195 }
09196 
09197 
09198 
09199 
09200 
09201 char * ISQ_surfgraph_label( MCW_arrowval * av , XtPointer cd )
09202 {
09203    switch( av->ival ){
09204       case 0:  return "No"  ;
09205       case 1:  return "Yes" ;
09206       case 2:  return "Inv" ;
09207    }
09208    return "?*?" ;
09209 }
09210 
09211 
09212 
09213 void ISQ_surfgraph_CB( MCW_arrowval * av , XtPointer cd )
09214 {
09215    MCW_imseq * seq = (MCW_imseq *) cd ;
09216 
09217 ENTRY("ISQ_surfgraph_CB") ;
09218 
09219    if( ! ISQ_VALID(seq) ) EXRETURN ;                
09220    if( av->ival == seq->surfgraph_num ) EXRETURN ;  
09221 
09222    seq->surfgraph_num = av->ival ;
09223 
09224    if( seq->surfgraph_num > 0 ) seq->need_orim |=  SURFGRAPH_MASK ;
09225    else                         seq->need_orim &= ~SURFGRAPH_MASK ;
09226    if( seq->need_orim == 0 ) KILL_1MRI(seq->orim) ;
09227 
09228    ISQ_redisplay( seq , -1 , isqDR_reimage ) ;  
09229    EXRETURN ;
09230 }
09231 
09232 
09233 
09234 void ISQ_surfgraph_draw( MCW_imseq * seq )
09235 {
09236    MEM_plotdata * mp ;
09237    ISQ_cbs cbs ;
09238    int ix , jy ;
09239 
09240 ENTRY("ISQ_surfgraph_draw") ;
09241 
09242    if( ! ISQ_REALZ(seq) ) EXRETURN ;  
09243 
09244    
09245 
09246    if( seq->surfgraph_num == 0 ){
09247      if( seq->surfgraph_mtd != NULL ){
09248        plotkill_topshell( seq->surfgraph_mtd ) ;
09249        seq->surfgraph_mtd = NULL ;
09250      }
09251      EXRETURN ;
09252    }
09253 
09254    if( seq->orim == NULL ) EXRETURN ;
09255 
09256    
09257 
09258    if( ISQ_SKIP_OVERLAY(seq) ){
09259       ix = jy = -1 ;
09260    } else {
09261       cbs.reason = isqCR_getxynim ;
09262       cbs.xim = cbs.yim = cbs.nim = -666 ;
09263       if( seq->status->send_CB != NULL )
09264 #if 0
09265          seq->status->send_CB( seq , seq->getaux , &cbs ) ;
09266 #else
09267          SEND(seq,cbs) ;
09268 #endif
09269       if( cbs.xim < 0 || cbs.yim < 0 ){
09270          ix = jy = -1 ;
09271       } else {
09272          ISQ_unflipxy( seq , &(cbs.xim) , &(cbs.yim) ) ;
09273          ix = cbs.xim ; jy = cbs.yim ;
09274       }
09275    }
09276 
09277    
09278 
09279    mp = plot_image_surface( seq->orim , (seq->surfgraph_num == 2) ? -1.0 : 1.0 ,
09280                             seq->surfgraph_theta , seq->surfgraph_phi ,
09281                             ix , jy ) ;
09282    if( mp == NULL ) EXRETURN ;
09283 
09284    
09285 
09286    if( seq->surfgraph_mtd != NULL ){
09287 
09288       MTD_replace_plotdata( seq->surfgraph_mtd , mp ) ;
09289       redraw_topshell( seq->surfgraph_mtd ) ;
09290 
09291    } else {  
09292 
09293       seq->surfgraph_mtd = memplot_to_topshell( seq->dc->display, mp, ISQ_surfgraph_mtdkill ) ;
09294 
09295       if( seq->surfgraph_mtd == NULL ){ delete_memplot( mp ); EXRETURN; }
09296 
09297       seq->surfgraph_mtd->userdata = (void *) seq ;
09298 
09299       
09300 
09301       seq->surfgraph_arrowpad = new_MCW_arrowpad( seq->surfgraph_mtd->form ,
09302                                                   ISQ_surfgraph_arrowpad_CB ,
09303                                                   (XtPointer) seq ) ;
09304 
09305       XtUnmanageChild( seq->surfgraph_arrowpad->wform ) ;
09306 
09307       XtVaSetValues( seq->surfgraph_arrowpad->wform ,
09308                         XmNbottomAttachment , XmATTACH_FORM ,
09309                         XmNrightAttachment  , XmATTACH_FORM ,
09310                         XmNleftAttachment   , XmATTACH_NONE ,
09311                         XmNtopAttachment    , XmATTACH_NONE ,
09312                         XmNwidth            , 60 ,
09313                         XmNheight           , 60 ,
09314                      NULL ) ;
09315 
09316       MCW_set_widget_bg( seq->surfgraph_arrowpad->wform , "white" , 0 ) ;
09317 
09318       XtManageChild( seq->surfgraph_arrowpad->wform ) ;
09319 
09320       seq->surfgraph_arrowpad->parent = (XtPointer) seq ;
09321       seq->surfgraph_arrowpad->fastdelay = MCW_AV_longdelay ;
09322    }
09323 
09324    EXRETURN ;
09325 }
09326 
09327 
09328 
09329 
09330 void ISQ_surfgraph_mtdkill( MEM_topshell_data * mp )
09331 {
09332    MCW_imseq * seq ;
09333 
09334 ENTRY("ISQ_surfgraph_mtdkill") ;
09335 
09336    if( mp == NULL ) EXRETURN ;
09337    seq = (MCW_imseq *) mp->userdata ; if( ! ISQ_VALID(seq) ) EXRETURN ;
09338 
09339    seq->surfgraph_mtd   = NULL ;
09340    seq->surfgraph_theta = DEFAULT_THETA  ;
09341    seq->surfgraph_phi   = DEFAULT_PHI ;
09342    myXtFree( seq->surfgraph_arrowpad ) ;
09343 
09344    seq->surfgraph_num = 0 ;
09345    AV_assign_ival( seq->surfgraph_av , 0 ) ;
09346    EXRETURN ;
09347 }
09348 
09349 
09350 
09351 MEM_plotdata * plot_image_surface( MRI_IMAGE * im , float fac ,
09352                                    float theta , float phi , int ix , int jy )
09353 {
09354    MRI_IMAGE * fim , * qim ;
09355    MEM_plotdata * mp ;
09356    float * x , * y , * z ;
09357    float  dx ,  dy , zbot,ztop ;
09358    int ii , nx , ny , nxy ;
09359    char str[128] ;
09360 
09361 ENTRY("plot_image_surface") ;
09362 
09363    if( im == NULL ) RETURN( NULL );
09364 
09365    
09366 
09367    nx = im->nx ; ny = im->ny ;
09368    if( nx < 3 || ny < 3 ) RETURN( NULL );
09369 
09370    create_memplot_surely( "imsurf" , 1.1 ) ;
09371 
09372    dx = im->dx ; if( dx <= 0.0 ) dx = 1.0 ;
09373    dy = im->dy ; if( dy <= 0.0 ) dy = 1.0 ;
09374 
09375    x = (float *) malloc( sizeof(float) * nx ) ;
09376    for( ii=0 ; ii < nx ; ii++ ) x[ii] = ii * dx ;
09377 
09378    y = (float *) malloc( sizeof(float) * ny ) ;
09379    for( ii=0 ; ii < ny ; ii++ ) y[ii] = ii * dy ;
09380 
09381    
09382 
09383    qim = mri_flippo( MRI_ROT_180 , 1 , im ) ;
09384    if( fac == 1.0 || fac == 0.0 ) fim = mri_to_float(qim) ;
09385    else                           fim = mri_scale_to_float(fac,qim) ;
09386    z = MRI_FLOAT_PTR(fim) ; mri_free(qim) ;
09387    nxy = nx * ny ; zbot = ztop = z[0] ;
09388    for( ii=1 ; ii < nxy ; ii++ ){
09389            if( z[ii] < zbot ) zbot = z[ii] ;
09390       else if( z[ii] > ztop ) ztop = z[ii] ;
09391    }
09392    ztop = ztop - zbot ;
09393    if( ztop > 0.0 ){
09394       ztop = 0.85 * sqrt( x[nx-1] * y[ny-1] ) / ztop ;
09395       for( ii=0 ; ii < nxy ; ii++ ) z[ii] = (z[ii]-zbot) * ztop ;
09396    }
09397 
09398    
09399 
09400    set_color_memplot( 0.0 , 0.0 , 0.0 ) ;
09401    set_thick_memplot( 0.0 ) ;
09402    plotpak_srface( x , y , z , nx , ny , theta, phi ) ;
09403 
09404    
09405 
09406    if( ix >= 0 && ix < nx && jy >= 0 && jy < ny ){
09407       real xi,yi,zi ; float xt,yt,zt , xtp,ytp,ztp ;
09408       ii = 1 ;
09409       xi = x[ix] ; yi = y[ny-1-jy] ; zi = z[ix+(ny-1-jy)*nx] ;
09410       (void) trn32s_( &xi , &yi , &zi ,
09411                       (real *)(&xt) , (real *)(&yt) , (real *)(&zt) ,
09412                       (integer *)(&ii) ) ;
09413 
09414 #undef  THIK
09415 #define THIK 0.003
09416 
09417       dx = 0.016 * x[nx-1] ; dy = 0.016 * y[ny-1] ; dx = MAX(dx,dy) ;
09418       xi = x[ix]+dx ; yi = y[ny-1-jy]+dx ; zi = z[ix+(ny-1-jy)*nx] ;
09419       (void) trn32s_( &xi , &yi , &zi ,
09420                       (real *)(&xtp) , (real *)(&ytp) , (real *)(&ztp) ,
09421                       (integer *)(&ii) ) ;
09422       dx = fabs(xtp-xt) ; dy = fabs(ytp-yt) ; dx = MAX(dx,dy) ;
09423 
09424       set_color_memplot( 0.8 , 0.0 , 0.2 ) ;
09425       set_thick_memplot( THIK ) ;
09426       plotpak_line( xt-dx , yt    , xt+dx , yt    ) ; 
09427       plotpak_line( xt    , yt-dx , xt    , yt+dx ) ; 
09428       plotpak_line( xt-dx , yt-dx , xt+dx , yt+dx ) ; 
09429       plotpak_line( xt+dx , yt-dx , xt-dx , yt+dx ) ; 
09430       set_color_memplot( 0.2 , 0.0 , 0.8 ) ;
09431       plotpak_line( xt+dx , yt-dx , xt+dx , yt+dx ) ; 
09432       plotpak_line( xt+dx , yt+dx , xt-dx , yt+dx ) ;
09433       plotpak_line( xt-dx , yt+dx , xt-dx , yt-dx ) ;
09434       plotpak_line( xt-dx , yt-dx , xt+dx , yt-dx ) ;
09435       set_color_memplot( 0.0 , 0.0 , 0.0 ) ;
09436       set_thick_memplot( 0.0 ) ;
09437    }
09438 
09439    free(x); free(y) ; mri_free(fim);
09440 
09441    plotpak_set( 0.0,1.0 , 0.0,1.0 , 0.0,1.0 , 0.0,1.0 , 1 ) ;
09442    sprintf(str,"\\theta=%.0f\\degree \\phi=%.0f\\degree",theta,phi) ;
09443    plotpak_pwritf( 1.099 , 0.97 , str, 19 , 0 , 1 ) ;
09444 
09445    mp = get_active_memplot() ; RETURN( mp );
09446 }
09447 
09448 
09449 
09450 void ISQ_surfgraph_arrowpad_CB( MCW_arrowpad * apad , XtPointer client_data )
09451 {
09452    MCW_imseq * seq = (MCW_imseq *) client_data ;
09453    XButtonEvent * xev = (XButtonEvent *) &(apad->xev) ;
09454    float step = 10.0 ;
09455 
09456 ENTRY("ISQ_surfgraph_arrowpad_CB") ;
09457 
09458    if( ! ISQ_REALZ(seq) ) EXRETURN ;  
09459 
09460    if( ( xev->type == ButtonPress || xev->type == ButtonRelease ) ){
09461       if( xev->state & (ShiftMask|ControlMask) ) step = 90.0 ; 
09462       if( xev->state & Mod1Mask                ) step =  2.0 ; 
09463    }
09464 
09465    switch( apad->which_pressed ){
09466       case AP_MID:   seq->surfgraph_theta = DEFAULT_THETA ;
09467                      seq->surfgraph_phi   = DEFAULT_PHI   ; break ;
09468 
09469       case AP_DOWN:  seq->surfgraph_theta += step ; break ;
09470       case AP_UP:    seq->surfgraph_theta -= step ; break ;
09471       case AP_LEFT:  seq->surfgraph_phi   += step ; break ;
09472       case AP_RIGHT: seq->surfgraph_phi   -= step ; break ;
09473 
09474       default:                                   EXRETURN ; 
09475    }
09476 
09477    while( seq->surfgraph_theta < 0.0    ) seq->surfgraph_theta += 360.0 ;
09478    while( seq->surfgraph_theta >= 360.0 ) seq->surfgraph_theta -= 360.0 ;
09479 
09480    while( seq->surfgraph_phi < 0.0    ) seq->surfgraph_phi += 360.0 ;
09481    while( seq->surfgraph_phi >= 360.0 ) seq->surfgraph_phi -= 360.0 ;
09482 
09483    ISQ_surfgraph_draw( seq ) ; EXRETURN ;
09484 }
09485 
09486 
09487 
09488 
09489 
09490 
09491 void ISQ_remove_widget( MCW_imseq * seq , Widget w )
09492 {
09493    int ii ;
09494 ENTRY("ISQ_remove_onoff") ;
09495 
09496    if( !ISQ_VALID(seq) || w == NULL ) EXRETURN ;
09497 
09498    XtUnmanageChild( w ) ;  
09499 
09500    for( ii=0 ; ii < seq->onoff_num ; ii++ ){     
09501      if( w == seq->onoff_widgets[ii] ){
09502        seq->onoff_widgets[ii] = NULL ;
09503        break ;
09504      }
09505    }
09506 
09507    for( ii=seq->onoff_num-1 ; ii > 0 ; ii-- ){   
09508      if( seq->onoff_widgets[ii] == NULL )
09509        seq->onoff_num = ii ;
09510      else
09511        break ;
09512    }
09513 
09514    EXRETURN ;
09515 }
09516 
09517 
09518 
09519 
09520 
09521 void ISQ_record_button( MCW_imseq * seq )
09522 {
09523    Widget rc , mbar , menu , cbut , wpar ;
09524    XmString xstr ;
09525 
09526 ENTRY("ISQ_record_button") ;
09527 
09528    
09529 
09530    
09531 
09532    seq->onoff_widgets[(seq->onoff_num)++] = seq->record_rc = rc =
09533      XtVaCreateWidget(
09534            "imseq" , xmRowColumnWidgetClass , seq->wform ,
09535               XmNorientation    , XmHORIZONTAL ,
09536               XmNpacking        , XmPACK_TIGHT ,
09537 
09538               LEADING_BOT       , XmATTACH_WIDGET              ,
09539               LEADING_WIDGET_BOT, seq->wbut_bot[NBUTTON_BOT-1] ,
09540               EDGING_BOT        , XmATTACH_FORM                ,
09541 
09542               XmNmarginWidth  , 1 ,
09543               XmNmarginHeight , 0 ,
09544               XmNmarginBottom , 0 ,
09545               XmNmarginTop    , 0 ,
09546               XmNmarginLeft   , 0 ,
09547               XmNmarginRight  , 0 ,
09548               XmNspacing      , 0 ,
09549               XmNborderWidth  , 0 ,
09550               XmNborderColor  , 0 ,
09551 
09552               XmNrecomputeSize , False ,
09553               XmNtraversalOn , False ,
09554               XmNinitialResourcesPersistent , False ,
09555            NULL ) ;
09556 
09557    
09558 
09559    mbar = XmCreateMenuBar( rc , "imseq" , NULL,0 ) ;
09560    XtVaSetValues( mbar ,
09561                      XmNmarginWidth  , 1 ,
09562                      XmNmarginHeight , 0 ,
09563                      XmNmarginBottom , 0 ,
09564                      XmNmarginTop    , 0 ,
09565                      XmNmarginLeft   , 0 ,
09566                      XmNmarginRight  , 0 ,
09567                      XmNspacing      , 0 ,
09568                      XmNborderWidth  , 0 ,
09569                      XmNborderColor  , 0 ,
09570                      XmNtraversalOn  , False ,
09571                      XmNbackground   , seq->dc->ovc->pixov_brightest ,
09572                   NULL ) ;
09573 
09574    
09575 
09576    menu = XmCreatePulldownMenu( mbar , "menu" , NULL,0 ) ;
09577    VISIBILIZE_WHEN_MAPPED(menu) ;
09578 
09579    
09580 
09581    xstr = XmStringCreateLtoR( "Rec" , XmFONTLIST_DEFAULT_TAG ) ;
09582    seq->record_cbut = cbut =
09583      XtVaCreateManagedWidget(
09584             "imseq" , xmCascadeButtonWidgetClass , mbar ,
09585                XmNlabelString , xstr ,
09586                XmNsubMenuId   , menu ,
09587                XmNmarginWidth , 1 ,
09588                XmNmarginHeight, 0 ,
09589                XmNmarginBottom, 0 ,
09590                XmNmarginTop   , 0 ,
09591                XmNmarginRight , 0 ,
09592                XmNmarginLeft  , 0 ,
09593                XmNtraversalOn , False ,
09594                XmNinitialResourcesPersistent , False ,
09595             NULL ) ;
09596    XmStringFree( xstr ) ;
09597    XtManageChild( mbar ) ;
09598    MCW_register_hint( cbut , "Turn image recording on/off" ) ;
09599    MCW_register_help( cbut ,
09600                       " \n"
09601                       "This menu controls image recording. Whenever the image\n"
09602                       "displayed is altered, an RGB copy of it can be saved\n"
09603                       "into a separate image buffer.  In this way, you can\n"
09604                       "build a sequence of images that can later be written\n"
09605                       "to disk for further processing (e.g., animation).\n"
09606                       "\n"
09607                       "---- These options control WHEN images  ----\n"
09608                       "---- will be recorded into the sequence ----\n"
09609                       "\n"
09610                       " Off      = don't record\n"
09611                       " Next One = record next image, then turn Off\n"
09612                       " Stay On  = record all images\n"
09613                       "\n"
09614                       "---- These options control WHERE new images ----\n"
09615                       "---- are to be stored into the sequence     ----\n"
09616                       "\n"
09617                       " After End    = at tail of sequence\n"
09618                       " Before Start = at head of sequence\n"
09619                       " Insert --    = insert before current sequence position\n"
09620                       " Insert ++    = insert after current sequence position\n"
09621                       " OverWrite    = replace current sequence position\n"
09622                       " -- OverWrite = replace image before current position\n"
09623                       " ++ OverWrite = replace image after current position\n"
09624                       "\n"
09625                       "---- HINTS and NOTES ----\n"
09626                       "\n"
09627                       "* You may want to set Xhairs to 'Off' on the AFNI\n"
09628                       "   control panel before recording images.\n"
09629                       "* The recording window is like a dataset image\n"
09630                       "   viewing window with most controls removed.\n"
09631                       "   The slider moves between recorded images, rather\n"
09632                       "   than between slices.\n"
09633                       "* The new 'Kill' button in the recording window lets\n"
09634                       "   you erase one image from the recorded sequence.\n"
09635                       "   Erased images, if not overwritten, will NOT be\n"
09636                       "   saved to disk.\n"
09637                       "* Use 'Save:bkg' in the recording window to save the\n"
09638                       "   sequence of recorded images to disk in PPM format.\n"
09639                       "   The recorded images are in color, and will be saved\n"
09640                       "   in color (despite the :bkg label on the Save button).\n"
09641                       "* You may want to use set 'Warp Anat on Demand' on\n"
09642                       "   the Datamode control panel to force the display\n"
09643                       "   voxels to be cubical.  Otherwise, the saved image\n"
09644                       "   pixels will have the same aspect ratio as the voxels\n"
09645                       "   in the dataset, which may not be square!\n"
09646                      ) ;
09647 
09648    
09649 
09650    xstr = XmStringCreateLtoR( "-- Cancel --" , XmFONTLIST_DEFAULT_TAG ) ;
09651    (void) XtVaCreateManagedWidget(
09652             "menu" , xmLabelWidgetClass , menu ,
09653                XmNlabelString , xstr ,
09654                XmNrecomputeSize , False ,
09655                XmNinitialResourcesPersistent , False ,
09656             NULL ) ;
09657    XmStringFree(xstr) ;
09658 
09659    (void) XtVaCreateManagedWidget(
09660             "menu" , xmSeparatorWidgetClass , menu ,
09661                XmNseparatorType , XmSINGLE_LINE ,
09662             NULL ) ;
09663 
09664    
09665 
09666    {  static char * status_label[3] = { "Off" , "Next One" , "Stay On" } ;
09667       static char * method_label[7] = { "After End"    ,
09668                                         "Before Start" ,
09669                                         "Insert --"    ,
09670                                         "Insert ++"    ,
09671                                         "OverWrite"    ,
09672                                         "-- OverWrite" ,
09673                                         "++ OverWrite"   } ;
09674 
09675       seq->record_status_bbox =
09676          new_MCW_bbox( menu , 3,status_label ,
09677                        MCW_BB_radio_one , MCW_BB_noframe ,
09678                        ISQ_record_CB , (XtPointer) seq ) ;
09679       seq->record_status = RECORD_STATUS_OFF ;
09680 
09681       (void) XtVaCreateManagedWidget(
09682                "menu" , xmSeparatorWidgetClass , menu ,
09683                   XmNseparatorType , XmSINGLE_LINE ,
09684                NULL ) ;
09685 
09686       seq->record_method_bbox =
09687          new_MCW_bbox( menu , 7,method_label ,
09688                        MCW_BB_radio_one , MCW_BB_noframe ,
09689                        ISQ_record_CB , (XtPointer) seq ) ;
09690       seq->record_method = RECORD_METHOD_AFTEREND ;
09691    }
09692 
09693    
09694 
09695    XtManageChild( rc ) ;
09696 
09697    
09698 
09699    seq->record_mode  = 0 ;    
09700    seq->record_imseq = NULL ; 
09701    seq->record_imarr = NULL ; 
09702    seq->record_mplot = NULL ; 
09703 
09704    EXRETURN ;
09705 }
09706 
09707 
09708 
09709 
09710 
09711 void ISQ_record_CB( Widget w, XtPointer client_data, XtPointer call_data )
09712 {
09713    MCW_imseq * seq = (MCW_imseq *) client_data ;
09714    int ib ;
09715 
09716 ENTRY("ISQ_record_CB") ;
09717 
09718    if( !ISQ_REALZ(seq) ) EXRETURN ;
09719 
09720    ib = MCW_val_bbox( seq->record_status_bbox ) ;
09721    if( ib != seq->record_status ){
09722       if( RECORD_ISON(ib) != RECORD_ISON(seq->record_status) )
09723          MCW_invert_widget( seq->record_cbut ) ;
09724       seq->record_status = ib ;
09725    }
09726 
09727    ib = MCW_val_bbox( seq->record_method_bbox ) ;
09728    if( ib != seq->record_method ){
09729       seq->record_method = ib ;
09730    }
09731 
09732    EXRETURN ;
09733 }
09734 
09735 
09736 
09737 
09738 
09739 
09740 
09741 
09742 
09743 
09744 
09745 
09746 
09747 
09748 
09749 void ISQ_record_addim( MCW_imseq * seq , int pos , int meth )
09750 {
09751    MRI_IMAGE * tim ;
09752    int opos , ii,bot,top ;
09753 
09754 ENTRY("ISQ_record_addim") ;
09755 
09756    
09757 
09758    if( !ISQ_REALZ(seq)        ||
09759        seq->record_mode       ||
09760        seq->given_xim == NULL   ) EXRETURN; 
09761 
09762    
09763 
09764    if( seq->record_imarr == NULL ){
09765      INIT_IMARR(seq->record_imarr) ;
09766      meth = 1 ;  
09767 
09768      seq->record_mplot = NULL ;  
09769    }
09770 
09771    
09772 
09773    tim = XImage_to_mri( seq->dc, seq->given_xim, X2M_USE_CMAP|X2M_FORCE_RGB );
09774 
09775    if( tim == NULL ) EXRETURN ; 
09776 
09777    
09778 
09779    opos = pos ;
09780    if( opos < 0 ){  
09781 
09782       if( seq->record_imseq != NULL ){
09783          drive_MCW_imseq( seq->record_imseq, isqDR_getimnr, (XtPointer)&opos );
09784               if( pos == -2 && opos > 0                                ) opos--;
09785          else if( pos == -3 && opos < IMARR_COUNT(seq->record_imarr)-1 ) opos++;
09786       }
09787       else
09788          opos = -1 ; 
09789 
09790    } else if( opos >= IMARR_COUNT(seq->record_imarr)-1 ) {
09791 
09792       opos = IMARR_COUNT(seq->record_imarr)-1 ;
09793    }
09794 
09795    if( opos < 0 ) meth = 1 ; 
09796 
09797    
09798 
09799    if( meth != 0 ){
09800 
09801       ADDTO_IMARR( seq->record_imarr , NULL ) ;  
09802       seq->record_mplot =(MEM_plotdata **)       
09803                          realloc( (void *)seq->record_mplot ,
09804                                   sizeof(MEM_plotdata *)
09805                                  *IMARR_COUNT(seq->record_imarr) ) ;
09806       bot = (meth < 0) ? opos : opos+1 ;         
09807       top = IMARR_COUNT(seq->record_imarr)-2 ;
09808       for( ii=top ; ii >= bot ; ii-- ){
09809         IMARR_SUBIM(seq->record_imarr,ii+1) = IMARR_SUBIM(seq->record_imarr,ii);
09810         seq->record_mplot[ii+1] = seq->record_mplot[ii] ;  
09811       }
09812 
09813       IMARR_SUBIM(seq->record_imarr,bot) = tim ; 
09814       seq->record_mplot[bot]             = copy_memplot( seq->mplot ) ;
09815 
09816    } else {  
09817 
09818       bot = opos ;
09819       mri_free( IMARR_SUBIM(seq->record_imarr,bot) ) ; 
09820       IMARR_SUBIM(seq->record_imarr,bot) = tim ;       
09821 
09822       delete_memplot( seq->record_mplot[bot] ) ;       
09823       seq->record_mplot[bot] = copy_memplot( seq->mplot ) ;
09824    }
09825 
09826    
09827 
09828    
09829 
09830    if( seq->record_imseq == NULL )
09831       ISQ_record_open( seq ) ;
09832    else
09833       ISQ_record_update( seq , bot ) ;
09834 
09835    EXRETURN ;
09836 }
09837 
09838 
09839 
09840 void ISQ_record_open( MCW_imseq * seq )
09841 {
09842    int ntot ;
09843 
09844 ENTRY("ISQ_record_open") ;
09845 
09846    if( !ISQ_REALZ(seq)                     ||
09847        seq->record_imarr == NULL           ||
09848        IMARR_COUNT(seq->record_imarr) == 0   ) EXRETURN ;
09849 
09850    ntot = IMARR_COUNT(seq->record_imarr) ;
09851 
09852    seq->record_imseq = open_MCW_imseq( seq->dc , ISQ_record_getim , seq ) ;
09853    seq->record_imseq->parent = seq ;
09854 
09855    drive_MCW_imseq( seq->record_imseq , isqDR_record_mode , NULL ) ;
09856 
09857    drive_MCW_imseq( seq->record_imseq , isqDR_realize, NULL ) ;
09858 
09859 #ifndef DONT_ONOFF_ONE
09860    if( ntot == 1 )
09861       drive_MCW_imseq( seq->record_imseq,isqDR_onoffwid,(XtPointer)isqDR_offwid);
09862    else
09863       drive_MCW_imseq( seq->record_imseq,isqDR_onoffwid,(XtPointer)isqDR_onwid );
09864 #endif
09865 
09866    drive_MCW_imseq( seq->record_imseq , isqDR_reimage , (XtPointer) (ntot-1) ) ;
09867 
09868    ISQ_set_cursor_state( seq , -1 ) ;  
09869    NORMAL_cursorize( seq->wbar ) ;
09870 
09871    EXRETURN ;
09872 }
09873 
09874 
09875 
09876 void ISQ_record_update( MCW_imseq * seq , int npos )
09877 {
09878    int ntot , ii ;
09879 
09880 ENTRY("ISQ_record_update") ;
09881 
09882    if( !ISQ_REALZ(seq)                     ||
09883        seq->record_imseq == NULL           ||
09884        seq->record_imarr == NULL           ||
09885        IMARR_COUNT(seq->record_imarr) == 0   ) EXRETURN ;
09886 
09887    ntot = IMARR_COUNT(seq->record_imarr) ;
09888 
09889         if( npos <  0    ) npos = 0 ;
09890    else if( npos >= ntot ) npos = ntot-1 ;
09891 
09892    drive_MCW_imseq( seq->record_imseq , isqDR_newseq , seq ) ;
09893 
09894 #ifndef DONT_ONOFF_ONE
09895    if( ntot == 1 )
09896       drive_MCW_imseq( seq->record_imseq,isqDR_onoffwid,(XtPointer)isqDR_offwid);
09897    else
09898       drive_MCW_imseq( seq->record_imseq,isqDR_onoffwid,(XtPointer)isqDR_onwid );
09899 #endif
09900 
09901    drive_MCW_imseq( seq->record_imseq , isqDR_reimage , (XtPointer)npos ) ;
09902 
09903    EXRETURN ;
09904 }
09905 
09906 
09907 
09908 
09909 
09910 
09911 XtPointer ISQ_record_getim( int n , int type , XtPointer handle )
09912 {
09913    int ntot = 0 ;
09914    MCW_imseq * seq = (MCW_imseq *) handle ;  
09915 
09916 ENTRY("ISQ_record_getim") ;
09917 
09918    if( seq->record_imarr != NULL ) ntot = IMARR_COUNT(seq->record_imarr) ;
09919    if( ntot < 1 ) ntot = 1 ;
09920 
09921    
09922 
09923    if( type == isqCR_getstatus ){
09924       MCW_imseq_status * stat = myXtNew( MCW_imseq_status ); 
09925                                                              
09926                                                              
09927       stat->num_total  = ntot ;
09928       stat->num_series = stat->num_total ;
09929       stat->send_CB    = ISQ_record_send_CB ;
09930       stat->parent     = NULL ;
09931       stat->aux        = NULL ;
09932 
09933       stat->transforms0D = NULL ;
09934       stat->transforms2D = NULL ;
09935 
09936       RETURN( (XtPointer)stat ) ;
09937    }
09938 
09939    
09940 
09941    if( type == isqCR_getoverlay ) RETURN(NULL) ;  
09942 
09943    if( type == isqCR_getmemplot ){                
09944      MEM_plotdata *mp ;
09945      if( seq->record_mplot == NULL ) RETURN(NULL) ;
09946      if( n < 0 ) n = 0 ; else if( n >= ntot ) n = ntot-1 ;
09947      mp = copy_memplot( seq->record_mplot[n] ) ;
09948      RETURN( (XtPointer)mp ) ;   
09949    }
09950 
09951    
09952 
09953 
09954    if( type == isqCR_getimage || type == isqCR_getqimage ){
09955       MRI_IMAGE * im = NULL , * rim ;
09956 
09957       if( seq->record_imarr != NULL ){
09958          if( n < 0 ) n = 0 ; else if( n >= ntot ) n = ntot-1 ;
09959          rim = IMARR_SUBIMAGE(seq->record_imarr,n) ;
09960          if( rim != NULL ) im = mri_to_rgb( rim ) ;
09961       }
09962       RETURN( (XtPointer)im ) ;
09963    }
09964 
09965    RETURN( NULL ) ; 
09966 }
09967 
09968 
09969 
09970 
09971 
09972 
09973 
09974 void ISQ_record_send_CB( MCW_imseq * seq , XtPointer handle , ISQ_cbs * cbs )
09975 {
09976 ENTRY("ISQ_record_send_CB") ;
09977 
09978    switch( cbs->reason ){
09979 
09980       case isqCR_destroy:{
09981          MCW_imseq * pseq = (MCW_imseq *) seq->parent ;
09982 
09983          
09984 
09985          pseq->record_imseq = NULL ;
09986          if( pseq->record_mplot != NULL && pseq->record_imarr != NULL ){
09987            int ib ;
09988            for( ib=0 ; ib < IMARR_COUNT(pseq->record_imarr) ; ib++ )
09989              delete_memplot( pseq->record_mplot[ib] ) ;
09990            free((void *)pseq->record_mplot) ; pseq->record_mplot = NULL ;
09991          }
09992          if( pseq->record_imarr != NULL ) DESTROY_IMARR(pseq->record_imarr) ;
09993          if( RECORD_ISON(pseq->record_status) ){
09994             pseq->record_status = RECORD_STATUS_OFF ;
09995             MCW_set_bbox( pseq->record_status_bbox , RECORD_STATUS_OFF ) ;
09996             MCW_invert_widget( pseq->record_cbut ) ;
09997          }
09998 
09999          
10000 
10001          myXtFree(seq->status) ; myXtFree(seq) ;
10002       }
10003       break ;
10004 
10005    }
10006 
10007    EXRETURN ;
10008 }
10009 
10010 
10011 
10012 void ISQ_record_kill_CB( Widget w, XtPointer client_data, XtPointer call_data )
10013 {
10014    MCW_imseq * seq = (MCW_imseq *) client_data ;
10015    MCW_imseq * pseq ;
10016    int pos=-1 ;
10017 
10018 ENTRY("ISQ_record_kill_CB") ;
10019 
10020    if( !ISQ_REALZ(seq) || !seq->record_mode ) EXRETURN ; 
10021 
10022    pseq = (MCW_imseq *) seq->parent ;  
10023 
10024    if( pseq->record_imarr == NULL ) EXRETURN ; 
10025 
10026    drive_MCW_imseq( seq , isqDR_getimnr, (XtPointer)&pos ) ; 
10027 
10028    if( pos < 0 || pos >= IMARR_COUNT(pseq->record_imarr) ) EXRETURN ;
10029 
10030    
10031 
10032    mri_free( IMARR_SUBIM(pseq->record_imarr,pos) ) ;
10033    IMARR_SUBIM(pseq->record_imarr,pos) = NULL ;
10034    delete_memplot( pseq->record_mplot[pos] ) ;  
10035    pseq->record_mplot[pos] = NULL ;
10036 
10037    ISQ_redisplay( seq , -1 , isqDR_display ) ;  
10038 
10039    EXRETURN ;
10040 }
10041 
10042 
10043 
10044 
10045 
10046 void ISQ_butsave_choice_CB( Widget w , XtPointer client_data ,
10047                                        MCW_choose_cbs * cbs   )
10048 {
10049    MCW_imseq * seq = (MCW_imseq *) client_data ;
10050    int pp , agif_ind=0 , mpeg_ind=0 , nstr ;
10051 
10052    if( !ISQ_REALZ(seq)               ||
10053        cbs->reason != mcwCR_integer  ||
10054        seq->dialog_starter==NBUT_DISP  ){  
10055 
10056       XBell(XtDisplay(w),100); POPDOWN_strlist_chooser ; return ;
10057    }
10058 
10059    nstr = ppmto_num+1 ;
10060    if( ppmto_agif_filter != NULL ) agif_ind = nstr++ ;
10061    if( ppmto_mpeg_filter != NULL ) mpeg_ind = nstr++ ;
10062 
10063    seq->opt.save_nsize = seq->opt.save_pnm
10064                        = seq->opt.save_agif = seq->opt.save_mpeg = 0 ;
10065 
10066    pp = cbs->ival ;
10067         if( pp == 0         ) seq->opt.save_filter=-1  ; 
10068    else if( pp <= ppmto_num ) seq->opt.save_filter=pp-1; 
10069    else if( pp == agif_ind  ) seq->opt.save_agif  = 1  ; 
10070    else if( pp == mpeg_ind  ) seq->opt.save_mpeg  = 1  ; 
10071 
10072    if( ppmto_agif_filter == NULL ) seq->opt.save_agif = 0 ;  
10073    if( ppmto_mpeg_filter == NULL ) seq->opt.save_mpeg = 0 ;
10074 
10075    SET_SAVE_LABEL(seq) ; return ;
10076 }
10077 
10078 
10079 
10080 
10081 
10082 
10083 void ISQ_butsave_EV( Widget w , XtPointer client_data ,
10084                      XEvent * ev , Boolean * continue_to_dispatch )
10085 {
10086    MCW_imseq * seq = (MCW_imseq *) client_data ;
10087 
10088    if( !ISQ_REALZ(seq) ) return ;
10089 
10090    ISQ_timer_stop(seq) ;
10091 
10092    switch( ev->type ){
10093       case ButtonPress:{
10094          XButtonEvent * event = (XButtonEvent *) ev ;
10095          if( event->button == Button3 ){
10096             char **strlist ; int pp , nstr , agif_ind=0 , mpeg_ind=0 ;
10097             if( seq->dialog_starter==NBUT_DISP ){XBell(XtDisplay(w),100); return; }
10098             strlist = (char **) malloc(sizeof(char *)*(ppmto_num+3)) ;
10099             strlist[0] = strdup("Save:bkg") ;             
10100             for( pp=0 ; pp < ppmto_num ; pp++ ){          
10101                strlist[pp+1] = AFMALL( char, 16) ;
10102                sprintf(strlist[pp+1],"Save.%.3s",ppmto_suffix[pp]) ;
10103             }
10104             nstr = ppmto_num+1 ;
10105             if( ppmto_agif_filter != NULL ){
10106                agif_ind = nstr ;
10107                strlist[nstr++] = strdup("Sav:aGif") ;     
10108             }
10109             if( ppmto_mpeg_filter != NULL ){
10110                mpeg_ind = nstr ;
10111                strlist[nstr++] = strdup("Sav:mpeg") ;     
10112             }
10113                  if(seq->opt.save_agif && agif_ind > 0 ) pp=agif_ind ;
10114             else if(seq->opt.save_mpeg && mpeg_ind > 0 ) pp=mpeg_ind ;
10115             else if(seq->opt.save_filter < 0)            pp=0        ;
10116             else                                     pp=seq->opt.save_filter+1 ;
10117             MCW_choose_strlist( w , "Image Save format" ,
10118                                 nstr , pp , strlist ,
10119                                 ISQ_butsave_choice_CB , (XtPointer) seq ) ;
10120             for( pp=0 ; pp < nstr ; pp++ ) free(strlist[pp]) ;
10121             free(strlist) ;
10122          } else if( event->button == Button2 ){
10123             XBell(XtDisplay(w),100) ;
10124             MCW_popup_message( w, " \n Ouch! \n ", MCW_USER_KILL );
10125 
10126          }
10127       }
10128       break ;
10129    }
10130    return ;
10131 }
10132 
10133 
10134 
10135 
10136 
10137 char * ISQ_getlabel( int nn , MCW_imseq *seq )
10138 {
10139    char *lab ;
10140 
10141 ENTRY("ISQ_getlabel") ;
10142 
10143 #if 0
10144    lab = (char *) seq->getim( nn,isqCR_getlabel,seq->getaux );
10145 #else
10146    AFNI_CALL_VALU_3ARG( seq->getim , char *,lab ,
10147                         int,nn , int,isqCR_getlabel , XtPointer,seq->getaux ) ;
10148 #endif
10149    RETURN(lab) ;
10150 }
10151 
10152 
10153 
10154 
10155 
10156 MEM_plotdata * ISQ_getmemplot( int nn , MCW_imseq *seq )
10157 {
10158    MEM_plotdata *mp ;
10159    int ntic ;
10160 
10161 ENTRY("ISQ_getmemplot") ;
10162 
10163 #if 0
10164    mp = (MEM_plotdata *) seq->getim( nn,isqCR_getmemplot,seq->getaux );
10165 #else
10166    AFNI_CALL_VALU_3ARG( seq->getim , MEM_plotdata *,mp ,
10167                         int,nn , int,isqCR_getmemplot , XtPointer,seq->getaux ) ;
10168 #endif
10169 
10170    if( mp != NULL && seq->cropit ){  
10171      float sx,sy,tx,ty ;
10172      float xa=seq->crop_xa, xb=seq->crop_xb, ya=seq->crop_ya, yb=seq->crop_yb ;
10173      float nxorg=seq->crop_nxorg , nyorg=seq->crop_nyorg ;
10174      MEM_plotdata *np ;
10175 
10176 
10177 
10178 
10179 
10180 
10181 
10182 
10183 
10184 
10185 
10186 
10187 
10188 
10189 
10190 
10191 
10192 
10193 
10194 
10195 
10196      sx = nxorg / (xb+1-xa) ;
10197      tx = -sx * xa / nxorg ;
10198 
10199      sy = nyorg / (yb+1-ya) ;
10200      ty = -sy * (1.0 - (yb+1) / nyorg) ;
10201 
10202      scale_memplot( sx,tx , sy,ty , 1.0 , mp ) ;    
10203      np = clip_memplot( 0.0,0.0 , 1.0,1.0 , mp ) ;  
10204      DESTROY_MEMPLOT(mp) ; mp = np ;
10205    }
10206 
10207    
10208 
10209    ntic = seq->wbar_ticnum_av->ival ;
10210    if( ntic > 0 ){
10211      MEM_plotdata *tp ;
10212      char *eee ;
10213      float rr=0.8,gg=1.0,bb=0.6 , tic, fac=1.0/ntic ;
10214      int it ;
10215 
10216      create_memplot_surely( "Iticplot" , 1.0 ) ;
10217      set_thick_memplot(0.0) ;
10218      eee = getenv("AFNI_IMAGE_LABEL_COLOR") ;
10219      if( eee != NULL )
10220        DC_parse_color( seq->dc , eee , &rr,&gg,&bb ) ;
10221      set_color_memplot(rr,gg,bb) ;
10222 
10223      tic = 0.01 * seq->wbar_ticsiz_av->ival ;  
10224 
10225      for( it=0 ; it <= ntic ; it++ ){
10226        plotpak_line( 0.0,it*fac , tic    ,it*fac ) ;
10227        plotpak_line( 1.0,it*fac , 1.0-tic,it*fac ) ;
10228        plotpak_line( it*fac,0.0 , it*fac ,tic    ) ;
10229        plotpak_line( it*fac,1.0 , it*fac ,1.0-tic) ;
10230      }
10231 
10232      
10233 
10234      tp = get_active_memplot() ;
10235      if( mp != NULL ){ append_to_memplot(mp,tp); delete_memplot(tp); }
10236      else              mp = tp ;
10237    }
10238 
10239    RETURN(mp) ;
10240 }
10241 
10242 
10243 
10244 
10245 
10246 MRI_IMAGE * ISQ_getoverlay( int nn , MCW_imseq *seq )
10247 {
10248    MRI_IMAGE *tim ;
10249 
10250 ENTRY("ISQ_getoverlay") ;
10251 
10252 #if 0
10253    tim = (MRI_IMAGE *) seq->getim( nn , isqCR_getoverlay , seq->getaux ) ;
10254 #else
10255    AFNI_CALL_VALU_3ARG( seq->getim , MRI_IMAGE *,tim ,
10256                         int,nn , int,isqCR_getoverlay , XtPointer,seq->getaux ) ;
10257 #endif
10258 
10259    if( tim == NULL ) RETURN(NULL) ;
10260 
10261    
10262 
10263    if( seq->cropit ){
10264      MRI_IMAGE *qim = mri_cut_2D( tim, seq->crop_xa,seq->crop_xb,
10265                                        seq->crop_ya,seq->crop_yb ) ;
10266      if( qim != NULL ){ mri_free(tim); tim = qim; }
10267    }
10268 
10269    RETURN(tim) ;
10270 }
10271 
10272 
10273 
10274 
10275 MRI_IMAGE * ISQ_getimage( int nn , MCW_imseq *seq )
10276 {
10277    int ii , rr , jj , ns , npix , ktim ;
10278    MRI_IMAGE *tim , *qim , *fim ;
10279    MRI_IMARR *imar ;
10280    float *far , val , *qar , **iar ;
10281 
10282 ENTRY("ISQ_getimage") ;
10283 
10284    
10285 
10286 #if 0
10287    tim = (MRI_IMAGE *) seq->getim( nn, isqCR_getimage, seq->getaux ) ;
10288 #else
10289    AFNI_CALL_VALU_3ARG( seq->getim , MRI_IMAGE *,tim ,
10290                         int,nn , int,isqCR_getimage , XtPointer,seq->getaux ) ;
10291 #endif
10292 
10293    if( tim == NULL ) RETURN(NULL) ;
10294 
10295    if( seq->cropit ){
10296 
10297      if( seq->crop_nxorg < 0 ){    
10298        seq->crop_nxorg = tim->nx ;
10299        seq->crop_nyorg = tim->ny ;
10300      }
10301 
10302      if( tim->nx != seq->crop_nxorg ||    
10303          tim->ny != seq->crop_nyorg   ){  
10304 
10305        seq->cropit = 0 ; seq->crop_nxorg = -1 ;
10306 
10307        if( seq->crop_drag ){              
10308          MCW_invert_widget( seq->crop_drag_pb ) ;
10309          seq->crop_drag = 0 ;
10310        }
10311 
10312      } else {
10313        MRI_IMAGE *cim = mri_cut_2D( tim, seq->crop_xa,seq->crop_xb,
10314                                          seq->crop_ya,seq->crop_yb ) ;
10315        if( cim != NULL ){ mri_free(tim); tim = cim; }
10316      }
10317    }
10318 
10319    
10320 
10321    if( !ISQ_DOING_SLICE_PROJ(seq) ) RETURN(tim) ;
10322 
10323    ns = seq->status->num_series ;
10324    rr = seq->slice_proj_range   ; if( rr > ns/2 ) rr = ns/2 ;
10325 
10326    if( rr                    == 0           ||
10327        seq->slice_proj_index == 0           ||
10328        seq->slice_proj_func  == NULL        ||
10329        tim                   == NULL        ||
10330        tim->kind             == MRI_rgb     ||
10331        tim->kind             == MRI_complex   ){
10332 
10333       RETURN(tim) ;
10334    }
10335 
10336    
10337 
10338    INIT_IMARR(imar) ;
10339 
10340    ktim = tim->kind ;  
10341 
10342    
10343 
10344    for( ii=-rr ; ii <= rr ; ii++ ){
10345 
10346       if( ii == 0 ){                
10347          fim = mri_to_float(tim) ;  
10348          ADDTO_IMARR(imar,fim) ;
10349          continue ;
10350       }
10351 
10352       jj = nn+ii ;                    
10353            if( jj < 0   ) jj = 0    ; 
10354       else if( jj >= ns ) jj = ns-1 ;
10355 
10356 #if 0
10357       qim = (MRI_IMAGE *) seq->getim( jj, isqCR_getimage, seq->getaux ) ;
10358 #else
10359       AFNI_CALL_VALU_3ARG( seq->getim , MRI_IMAGE *,qim ,
10360                            int,jj , int,isqCR_getimage , XtPointer,seq->getaux ) ;
10361 #endif
10362 
10363       if( qim == NULL )
10364          fim = mri_to_float(tim) ;                 
10365       else if( qim->kind != MRI_float ){
10366          fim = mri_to_float(qim) ; mri_free(qim) ; 
10367       } else
10368          fim = qim ;                               
10369 
10370       if( seq->cropit ){
10371         MRI_IMAGE *cim = mri_cut_2D( fim , seq->crop_xa,seq->crop_xb,
10372                                            seq->crop_ya,seq->crop_yb ) ;
10373         if( cim != NULL ){ mri_free(fim); fim = cim; }
10374       }
10375 
10376       ADDTO_IMARR(imar,fim) ;
10377    }
10378 
10379    
10380 
10381    qim = mri_new_conforming( tim , MRI_float ) ;
10382    qar = MRI_FLOAT_PTR(qim) ; MRI_COPY_AUX(qim,tim) ;
10383    mri_free(tim) ;
10384 
10385    npix = qim->nvox ;
10386    rr   = 2*rr+1 ;
10387    far  = (float * ) malloc( sizeof(float  ) * rr ) ;
10388    iar  = (float **) malloc( sizeof(float *) * rr ) ;
10389 
10390    for( ii=0 ; ii < rr ; ii++ )
10391       iar[ii] = MRI_FLOAT_PTR(IMARR_SUBIM(imar,ii)) ;
10392 
10393    for( jj=0 ; jj < npix ; jj++ ){
10394 
10395       for( ii=0 ; ii < rr ; ii++ ) far[ii] = iar[ii][jj] ;
10396 
10397 #if 0
10398       val = seq->slice_proj_func( rr , far ) ;
10399 #else
10400       AFNI_CALL_proj_function( seq->slice_proj_func , rr,far , val ) ;
10401 #endif
10402 
10403       qar[jj] = val ;
10404    }
10405 
10406    free(iar) ; free(far) ; DESTROY_IMARR(imar) ;
10407 
10408    if( ktim != MRI_float ){
10409       tim = mri_to_mri(ktim,qim); mri_free(qim); qim = tim;
10410    }
10411 
10412    RETURN(qim) ;
10413 }
10414 
10415 
10416 
10417 
10418 
10419 void ISQ_cropper( MCW_imseq *seq , XButtonEvent *event )
10420 {
10421 #define MINCROP 9
10422 
10423    int x1=event->x,y1=event->y , x2,y2 ;
10424    int imx1,imy1,nim1 , imx2,imy2,nim2 , tt ;
10425    int zlev = seq->zoom_fac ;
10426 
10427 ENTRY("ISQ_cropper") ;
10428 
10429    if( !seq->crop_allowed ){
10430      XBell(seq->dc->display,100); EXRETURN;
10431    }
10432 
10433    
10434 
10435 
10436 
10437 #if 1
10438    RWC_drag_rectangle( seq->wimage , x1,y1,&x2,&y2 ) ;
10439 #else
10440    { int rad ;
10441      RWC_drag_circle( seq->wimage , x1,y1 , &rad ) ;  
10442      fprintf(stderr,"rad=%d\n",rad) ; EXRETURN ;
10443    }
10444 #endif
10445 
10446    
10447 
10448    ISQ_mapxy( seq , x1,y1 , &imx1,&imy1,&nim1 ) ;
10449    ISQ_mapxy( seq , x2,y2 , &imx2,&imy2,&nim2 ) ;
10450 
10451    
10452 
10453    if( imx1 > imx2 ){ tt = imx1; imx1 = imx2; imx2 = tt; }
10454    if( imy1 > imy2 ){ tt = imy1; imy1 = imy2; imy2 = tt; }
10455 
10456    
10457 
10458 
10459    if( nim1 != nim2 || imx1 < 0 || imy1 < 0 ){
10460      static int npop=0 ;
10461      char str[64] ;
10462      if( npop < 5 ){
10463 #define NINSULT 17
10464        static char *ins[NINSULT]={
10465                       "Stupid","Moronic","Cretinous","Idiotic","Bozonic",
10466                       "Criminal","Repulsive","Dumb",
10467                       "Pinheaded","Fatuous","Asinine","Imbecilic",
10468                       "Oafish","Doltish","Duncical","Witless","Brainless" };
10469        int ii = (lrand48()>>5) % NINSULT ;
10470        sprintf(str," \n  %s \n  crop\n  rectangle! \n ",ins[ii]) ;
10471        MCW_popup_message( seq->wimage,str, MCW_USER_KILL|MCW_TIMER_KILL ) ;
10472        npop++ ;
10473      }
10474      XBell(seq->dc->display,100); goto CropDone;
10475    }
10476 
10477    
10478 
10479    if( imx2-imx1 < MINCROP || imy2-imy1 < MINCROP ){ 
10480      if( imx2-imx1 < 2 || imy2-imy1 < 2 ){
10481        seq->cropit = 0 ; seq->crop_nxorg = -1 ;  
10482      } else {
10483        XBell(seq->dc->display,100);                 
10484      }
10485 
10486    
10487 
10488    } else {
10489 
10490      
10491 
10492      if( zlev > 1 ){
10493 
10494        
10495        
10496        
10497 
10498        int xmid=(imx2+imx1)/2, xh=(imx2-imx1)/2, xhw=zlev*xh ;
10499        int ymid=(imy2+imy1)/2, yh=(imy2-imy1)/2, yhw=zlev*yh ;
10500        int nx,ny ;
10501        float mh = (zlev-1.001)/zlev ;  
10502 
10503        
10504 
10505        nx = (seq->crop_nxorg > 0) ? seq->crop_nxorg : seq->horig ;
10506        ny = (seq->crop_nxorg > 0) ? seq->crop_nyorg : seq->vorig ;
10507 #if 0
10508 fprintf(stderr,"Crop: imx1=%d imx2=%d xmid=%d xh=%d xhw=%d nx=%d\n",imx1,imx2,xmid,xh,xhw,nx);
10509 fprintf(stderr,"      imy1=%d imy2=%d ymid=%d yh=%d yhw=%d ny=%d\n",imy1,imy2,ymid,yh,yhw,ny);
10510 #endif
10511 
10512        
10513 
10514 
10515 
10516 
10517 
10518 
10519        imx1 = xmid-xhw ; imx2 = xmid+xhw ;
10520             if( imx1 <  0    ){ imx1 = 0   ; imx2 = imx1+2*xhw; }
10521        else if( imx2 >= nx-1 ){ imx2 = nx-1; imx1 = imx2-2*xhw; }
10522        imy1 = ymid-yhw ; imy2 = ymid+yhw ;
10523             if( imy1 <  0    ){ imy1 = 0   ; imy2 = imy1+2*yhw; }
10524        else if( imy2 >= ny-1 ){ imy2 = ny-1; imy1 = imy2-2*yhw; }
10525 
10526        
10527 
10528 
10529        if( seq->opt.mirror )
10530          seq->zoom_hor_off = ((float)(imx2-xmid-xh))
10531                             /((float)(imx2-imx1)) ;
10532        else
10533          seq->zoom_hor_off = ((float)(xmid-xh-imx1))
10534                             /((float)(imx2-imx1)) ;
10535 
10536        seq->zoom_ver_off = ((float)(ymid-yh-imy1))
10537                           /((float)(imy2-imy1)) ;
10538 #if 0
10539 fprintf(stderr,"      imx1=%d imx2=%d hor_off=%f\n",imx1,imx2,seq->zoom_hor_off);
10540 fprintf(stderr,"      imy1=%d imy2=%d ver_off=%f\n",imy1,imy2,seq->zoom_ver_off);
10541 #endif
10542 
10543        
10544 
10545             if( seq->zoom_hor_off > mh  ) seq->zoom_hor_off = mh  ;
10546        else if( seq->zoom_hor_off < 0.0 ) seq->zoom_hor_off = 0.0 ;
10547             if( seq->zoom_ver_off > mh  ) seq->zoom_ver_off = mh  ;
10548        else if( seq->zoom_ver_off < 0.0 ) seq->zoom_ver_off = 0.0 ;
10549 
10550      } 
10551 
10552      
10553 
10554      seq->crop_xa = imx1 ; seq->crop_xb = imx2 ;
10555      seq->crop_ya = imy1 ; seq->crop_yb = imy2 ;
10556      seq->cropit = 1 ; seq->crop_nxorg = -1 ;
10557    }
10558 
10559    
10560 
10561 CropDone:
10562    if( seq->crop_drag ){                       
10563      MCW_invert_widget( seq->crop_drag_pb ) ;  
10564      seq->crop_drag = 0 ;
10565    }
10566 
10567    ISQ_redisplay( seq , -1 , isqDR_display ) ;
10568    EXRETURN ;
10569 }
10570 
10571 
10572 
10573 
10574 
10575 
10576 static void SNAP_warnhandler(char * msg){ return ; }
10577 
10578 
10579 
10580 static MCW_imseq *snap_isq  = NULL ;
10581 static MCW_DC    *snap_dc   = NULL ;  
10582 static MRI_IMARR *snap_imar = NULL ;
10583 
10584 static void SNAP_imseq_send_CB( MCW_imseq *, XtPointer, ISQ_cbs * ) ;
10585 
10586 
10587 
10588 
10589 
10590 
10591 static XtPointer SNAP_imseq_getim( int n, int type, XtPointer handle )
10592 {
10593    int ntot = 0 ;
10594 
10595 ENTRY("SNAP_imseq_getim") ;
10596 
10597    if( snap_imar != NULL ) ntot = IMARR_COUNT(snap_imar) ;
10598    if( ntot < 1 ) ntot = 1 ;
10599 
10600    
10601 
10602    if( type == isqCR_getstatus ){
10603      MCW_imseq_status *stat = myXtNew( MCW_imseq_status ) ; 
10604                                                             
10605                                                             
10606      stat->num_total  = ntot ;
10607      stat->num_series = ntot ;
10608      stat->send_CB    = SNAP_imseq_send_CB ;
10609      stat->parent     = NULL ;
10610      stat->aux        = NULL ;
10611 
10612      stat->transforms0D = NULL ;
10613      stat->transforms2D = NULL ;
10614      stat->slice_proj   = NULL ;
10615 
10616      RETURN( (XtPointer)stat ) ;
10617    }
10618 
10619    
10620 
10621 
10622    if( type == isqCR_getimage || type == isqCR_getqimage ){
10623      MRI_IMAGE *im = NULL , *rim ;
10624 
10625      if( snap_imar != NULL ){
10626        if( n < 0 ) n = 0 ; else if( n >= ntot ) n = ntot-1 ;
10627        rim = IMARR_SUBIMAGE(snap_imar,n) ;
10628        im  = mri_copy( rim ) ;
10629      }
10630      RETURN( (XtPointer)im );
10631    }
10632 
10633    RETURN( NULL ) ; 
10634 }
10635 
10636 
10637 
10638 
10639 
10640 
10641 
10642 static void SNAP_imseq_send_CB( MCW_imseq *seq, XtPointer handle, ISQ_cbs *cbs )
10643 {
10644 ENTRY("SNAP_imseq_send_CB") ;
10645    switch( cbs->reason ){
10646      case isqCR_destroy:{
10647        myXtFree(snap_isq) ;         snap_isq  = NULL ;
10648        DESTROY_IMARR( snap_imar ) ; snap_imar = NULL ;
10649      }
10650      break ;
10651    }
10652    EXRETURN ;
10653 }
10654 
10655 
10656 
10657 static void SNAP_make_dc( Widget w )
10658 {
10659 ENTRY("SNAP_make_dc") ;
10660    if( snap_dc == NULL ){
10661      if( first_dc != NULL ) snap_dc = first_dc ;
10662      else{
10663        if( w == (Widget) NULL ){
10664          fprintf(stderr,"** Can't snapshot/save with NULL widget!\n") ;
10665          EXRETURN ;
10666        }
10667        (void ) XtAppSetWarningHandler( XtWidgetToApplicationContext(w),
10668                                        SNAP_warnhandler ) ;
10669        snap_dc = MCW_new_DC( w, 4,0, NULL,NULL, 1.0,0 ) ;
10670      }
10671    }
10672    EXRETURN ;
10673 }
10674 
10675 
10676 
10677 
10678 static void SNAP_store_image( MRI_IMAGE *tim , Widget w )
10679 {
10680 ENTRY("SNAP_store_image") ;
10681 
10682    if( tim == NULL ) EXRETURN ;
10683 
10684    if( snap_imar == NULL ) INIT_IMARR(snap_imar) ;
10685 
10686    if( IMARR_COUNT(snap_imar) > 0 ){
10687      MRI_IMAGE *qim = IMARR_LASTIM( snap_imar ) ;
10688      if( mri_equal(qim,tim) ){
10689        fprintf(stderr,"++ Image recorder: reject duplicate image at #%d\n",
10690                IMARR_COUNT(snap_imar)-1 ) ;
10691        mri_free(tim); EXRETURN;
10692      }
10693    }
10694 
10695    ADDTO_IMARR(snap_imar,tim) ;
10696 
10697    
10698 
10699    if( snap_isq == NULL ){
10700      int xr,yr , wx,hy , xx,yy ;
10701      Position xroot,yroot ;
10702      Widget wpar ;
10703 
10704      SNAP_make_dc( w ) ; if( snap_dc == NULL ) EXRETURN ;
10705 
10706      snap_isq = open_MCW_imseq( snap_dc, SNAP_imseq_getim, NULL ) ;
10707 
10708      drive_MCW_imseq( snap_isq, isqDR_periodicmont, (XtPointer) 0 ) ;
10709      drive_MCW_imseq( snap_isq, isqDR_realize     , NULL          ) ;
10710      drive_MCW_imseq( snap_isq, isqDR_title       , "Snapshots"   ) ;
10711 
10712      
10713 
10714      if( w != (Widget) NULL ){
10715        wpar = w ;
10716        while( XtParent(wpar) != NULL ) wpar = XtParent(wpar) ;  
10717        XtTranslateCoords( wpar , 0,0 , &xroot,&yroot ) ;
10718        xr = (int) xroot ; yr = (int) yroot ;
10719        MCW_widget_geom( wpar , &wx,NULL , NULL,NULL ) ;
10720        xx = 1+wx+xr ; yy = 1+yr ;
10721        if( xx >= snap_dc->width-wx/3 ){
10722          XLowerWindow( snap_dc->display , XtWindow(wpar) ) ; xx = yy = 2 ;
10723        }
10724        XtVaSetValues( snap_isq->wtop , XmNx,xx , XmNy,yy , NULL ) ;
10725      }
10726    }
10727 
10728    
10729 
10730    if( IMARR_COUNT(snap_imar) > 1 ){
10731      int ii ;
10732      drive_MCW_imseq( snap_isq, isqDR_newseq      , NULL ) ;
10733      drive_MCW_imseq( snap_isq, isqDR_onoffwid    , (XtPointer)isqDR_onwid  );
10734 
10735      
10736 
10737      XtUnmanageChild( snap_isq->wbar ) ;
10738      XtUnmanageChild( snap_isq->arrowpad->wform ) ;
10739      for( ii=0 ; ii < NBUTTON_RIG ; ii++)
10740        XtUnmanageChild( snap_isq->wbut_rig[ii] ) ;
10741      for( ii=0 ; ii < NARROW-1 ; ii++ ) 
10742        XtUnmanageChild( snap_isq->arrow[ii]->wrowcol ) ;
10743      XtUnmanageChild( snap_isq->ov_opacity_sep ) ;
10744      XtUnmanageChild( snap_isq->ov_opacity_av->wrowcol ) ;
10745      XtUnmanageChild( snap_isq->winfo ) ;
10746      XtUnmanageChild( snap_isq->pen_bbox->wrowcol ) ;
10747 
10748    } else {
10749      drive_MCW_imseq( snap_isq, isqDR_onoffwid    , (XtPointer)isqDR_offwid );
10750    }
10751 
10752    
10753 
10754    ISQ_redisplay( snap_isq , IMARR_COUNT(snap_imar)-1 , isqDR_display ) ;
10755 
10756    EXRETURN ;
10757 }
10758 
10759 
10760 
10761 
10762 
10763 
10764 void ISQ_snapshot( Widget w )
10765 {
10766    MRI_IMAGE *tim ;
10767    Window win ;
10768 
10769 ENTRY("ISQ_snapshot") ;
10770 
10771    if( w == NULL || !XtIsWidget(w) )         EXRETURN ;
10772    if( !XtIsRealized(w) || !XtIsManaged(w) ) EXRETURN ;
10773    win = XtWindow(w); if( win == (Window)0 ) EXRETURN ;
10774 
10775    
10776 
10777    SNAP_make_dc( w ) ; if( snap_dc == NULL ) EXRETURN ;
10778 
10779    tim = SNAP_grab_image( w , snap_dc ) ;
10780    if( tim == NULL )                         EXRETURN ;
10781 
10782    
10783 
10784    SNAP_store_image( tim , w ) ;
10785    EXRETURN ;
10786 }
10787 
10788 
10789 
10790 
10791 
10792 
10793 
10794 
10795 
10796 
10797 void ISQ_snapsave( int ww , int hh , byte *pix , Widget w )
10798 {
10799    MRI_IMAGE *tim ;
10800    byte *qix ;
10801    int ii , jj , flip=0 ;
10802 
10803 ENTRY("ISQ_snapsave") ;
10804 
10805    if( ww < 2 || pix == NULL ) EXRETURN ;
10806    if( hh < 0 ){ hh = -hh ; flip = 1 ; }
10807    if( hh < 2 ) EXRETURN ;
10808 
10809    SNAP_make_dc( w ) ; if( snap_dc == NULL ) EXRETURN ;
10810 
10811    tim = mri_new( ww,hh, MRI_rgb ) ; qix = MRI_RGB_PTR(tim) ;
10812 
10813    if( flip ){                    
10814      for( jj=0 ; jj < hh ; jj++ )
10815        memcpy( qix+3*ww*(hh-jj-1) , pix+3*ww*jj , 3*ww ) ;
10816    } else {                                                   
10817      memcpy( qix , pix , 3*ww*hh ) ;
10818    }
10819 
10820    SNAP_store_image( tim , w ) ;
10821    EXRETURN ;
10822 }
10823 
10824 
10825 
10826 void ISQ_pen_bbox_CB( Widget w, XtPointer client_data, XtPointer call_data )
10827 {
10828    MCW_imseq *seq = (MCW_imseq *)client_data ;
10829    int val ;
10830 
10831 ENTRY("ISQ_pen_bbox_CB") ;
10832    if( !ISQ_REALZ(seq) ) EXRETURN ;                 
10833 
10834    if( !seq->button2_enabled ){                     
10835      MCW_set_bbox( seq->pen_bbox , 0 ) ;
10836      ISQ_set_cursor_state( seq, CURSOR_NORMAL ) ;
10837      XtUnmanageChild( seq->pen_bbox->wrowcol ) ;
10838      EXRETURN ;
10839    }
10840 
10841    val = MCW_val_bbox( seq->pen_bbox ) ;
10842    ISQ_set_cursor_state( seq, (val==0) ? CURSOR_NORMAL : CURSOR_PENCIL ) ;
10843    EXRETURN ;
10844 }
10845 
10846 
10847 
10848 
10849 void ISQ_timer_CB( XtPointer cd , XtIntervalId *id ) 
10850 {
10851    MCW_imseq *seq = (MCW_imseq *)cd ;
10852    int redo = 0 ;
10853 
10854 ENTRY("ISQ_timer_CB") ;
10855 
10856    if( !ISQ_REALZ(seq) || seq->timer_id == 0 ) EXRETURN ;
10857 
10858    switch( seq->timer_func ){
10859 
10860      case ISQ_TIMERFUNC_INDEX:{
10861        int nn=seq->im_nr , nt=seq->status->num_total ;
10862        if( nt > 1 && seq->timer_param != 0 ){
10863          nn = (nn+seq->timer_param+nt) % nt ;
10864          ISQ_redisplay( seq , nn , isqDR_display ) ;
10865          redo = 1 ;
10866        }
10867      }
10868      break ;
10869 
10870      case ISQ_TIMERFUNC_BOUNCE:{
10871        int nn=seq->im_nr , nt=seq->status->num_total ;
10872        if( nt > 1 && seq->timer_param != 0 ){
10873          nn = nn + seq->timer_param ;
10874          if( nn <  0  ){
10875            nn = -nn; seq->timer_param = -seq->timer_param;
10876          } else if( nn >= nt ){
10877            nn = 2*(nt-1)-nn; seq->timer_param = -seq->timer_param;
10878          }
10879          ISQ_redisplay( seq , nn , isqDR_display ) ;
10880          redo = 1 ;
10881        }
10882      }
10883      break ;
10884 
10885    }
10886 
10887    if( redo ) seq->timer_id = XtAppAddTimeOut(
10888                                XtWidgetToApplicationContext(seq->wform) ,
10889                                seq->timer_delay , ISQ_timer_CB , seq ) ;
10890    else       seq->timer_id = 0 ;
10891 
10892    EXRETURN ;
10893 }
10894 
10895 void ISQ_timer_stop( MCW_imseq *seq )
10896 {
10897 ENTRY("ISQ_timer_stop") ;
10898    if( seq != NULL && seq->timer_id > 0 ){
10899      XtRemoveTimeOut(seq->timer_id); seq->timer_id = 0;
10900    }
10901    EXRETURN ;
10902 }
10903 
10904 
10905 
10906 
10907 
10908 
10909 int ISQ_handle_keypress( MCW_imseq *seq , unsigned long key )
10910 {
10911    static int busy=0 ;   
10912 
10913 ENTRY("ISQ_handle_keypress") ;
10914 
10915    ISQ_timer_stop(seq) ;  
10916 
10917    if( busy || key == 0 ) RETURN(1) ;
10918    busy = 1 ;
10919 
10920    
10921 
10922    if( key > 255 ){
10923      KeySym ks = (KeySym)key ;
10924      switch( ks ){
10925 
10926        case XK_Left:
10927        case XK_KP_Left:
10928          seq->arrowpad->which_pressed = AP_LEFT ;
10929          seq->arrowpad->xev.type = 0 ;
10930          ISQ_arrowpad_CB( seq->arrowpad , (XtPointer)seq ) ;
10931        break ;
10932 
10933        case XK_Right:
10934        case XK_KP_Right:
10935          seq->arrowpad->which_pressed = AP_RIGHT ;
10936          seq->arrowpad->xev.type = 0 ;
10937          ISQ_arrowpad_CB( seq->arrowpad , (XtPointer)seq ) ;
10938        break ;
10939 
10940        case XK_Down:
10941        case XK_KP_Down:
10942          seq->arrowpad->which_pressed = AP_DOWN ;
10943          seq->arrowpad->xev.type = 0 ;
10944          ISQ_arrowpad_CB( seq->arrowpad , (XtPointer)seq ) ;
10945        break ;
10946 
10947        case XK_Up:
10948        case XK_KP_Up:
10949          seq->arrowpad->which_pressed = AP_UP ;
10950          seq->arrowpad->xev.type = 0 ;
10951          ISQ_arrowpad_CB( seq->arrowpad , (XtPointer)seq ) ;
10952        break ;
10953 
10954        case XK_Page_Up:
10955        case XK_KP_Page_Up:
10956        case XK_Page_Down:
10957        case XK_KP_Page_Down:{
10958          int nn=seq->im_nr , nt=seq->status->num_total ;
10959          if( nt > 1 ){
10960            if( ks==XK_Page_Down || ks==XK_KP_Page_Down ){ nn--; if(nn< 0 ) nn=nt-1; }
10961            else                                         { nn++; if(nn>=nt) nn=0   ; }
10962 #if 1
10963            ISQ_redisplay( seq , nn , isqDR_display ) ;
10964 #else
10965            ISQ_set_image_number( seq , nn ) ;
10966 #endif
10967          }
10968        }
10969        break ;
10970 
10971        case XK_Delete:              
10972        case XK_KP_Delete:
10973          if( seq->button2_enabled && seq->status->send_CB != NULL ){
10974            ISQ_cbs cbs ;
10975            cbs.reason   = isqCR_button2_key ;
10976            cbs.key      = (int) XK_Delete ;
10977 #if 0
10978            seq->status->send_CB( seq , seq->getaux , &cbs ) ;
10979 #else
10980            SEND(seq,cbs) ;
10981 #endif
10982          }
10983        break ;
10984 
10985        
10986 
10987        case XK_F2:{
10988          if( !seq->button2_enabled ){
10989            MCW_popup_message( seq->wimage,
10990                               " \n Only when \n"
10991                               " Drawing!! \n ", MCW_USER_KILL );
10992            XBell(seq->dc->display,100); busy=0; RETURN(0);
10993          }
10994 
10995          ISQ_set_cursor_state( seq ,
10996                                (seq->cursor_state == CURSOR_PENCIL)
10997                                ? CURSOR_NORMAL : CURSOR_PENCIL ) ;
10998        }
10999        break ;
11000 
11001        default:
11002        case XK_Home:
11003        case XK_F3:
11004        case XK_F4:
11005        case XK_F5:
11006        case XK_F6:
11007        case XK_F7:
11008        case XK_F8:
11009        case XK_F9:
11010        case XK_F10:
11011        case XK_F11:
11012        case XK_F12:
11013 #if 0
11014          XBell(seq->dc->display,100) ;
11015          MCW_popup_message( seq->wimage, " \n Ouch! \n ", MCW_USER_KILL );
11016          AFNI_speak( "Ouch!" , 0 ) ;
11017 #endif
11018        break ;
11019      }
11020      busy=0; RETURN(1) ;
11021    }
11022 
11023          
11024 
11025    switch( key ){
11026 
11027      
11028 
11029      case 'q':
11030      case 'Q':{
11031        ISQ_but_done_CB( NULL, (XtPointer)seq, NULL ) ;
11032        busy=0; RETURN(1) ;
11033      }
11034      break ;
11035 
11036      
11037 
11038      case 'v':
11039      case 'V':{
11040        if( seq->button2_enabled ){
11041          MCW_popup_message( seq->wimage,
11042                                " \n Not when \n"
11043                                " Drawing! \n ", MCW_USER_KILL );
11044          XBell(seq->dc->display,100) ;
11045        } else if( seq->status->num_total > 1 ){      
11046          seq->timer_func  = ISQ_TIMERFUNC_INDEX ;
11047          seq->timer_delay = (int) AFNI_numenv("AFNI_VIDEO_DELAY") ;
11048          if( seq->timer_delay <= 0 ) seq->timer_delay = 1 ;
11049          seq->timer_param = (key == 'v') ? 1 : -1 ;
11050          seq->timer_id    =
11051            XtAppAddTimeOut( XtWidgetToApplicationContext(seq->wform) ,
11052                             seq->timer_delay , ISQ_timer_CB , seq ) ;
11053        }
11054        busy=0; RETURN(1) ;
11055      }
11056      break ;
11057 
11058      case 'r':
11059      case 'R':{
11060        if( seq->button2_enabled ){
11061          MCW_popup_message( seq->wimage,
11062                               " \n Not when \n"
11063                               " Drawing! \n ", MCW_USER_KILL );
11064          XBell(seq->dc->display,100) ;
11065        } else if( seq->status->num_total > 1 ){      
11066          seq->timer_func  = ISQ_TIMERFUNC_BOUNCE ;
11067          seq->timer_delay = (int) AFNI_numenv("AFNI_VIDEO_DELAY") ;
11068          if( seq->timer_delay <= 0 ) seq->timer_delay = 1 ;
11069          seq->timer_param = (key == 'r') ? 1 : -1 ;
11070          seq->timer_id    =
11071            XtAppAddTimeOut( XtWidgetToApplicationContext(seq->wform) ,
11072                             seq->timer_delay , ISQ_timer_CB , seq ) ;
11073        }
11074        busy=0; EXRETURN ;
11075      }
11076      break ;
11077 
11078      
11079 
11080 
11081      case '>':
11082      case '<':{
11083        int nn=seq->im_nr , nt=seq->status->num_total ;
11084        if( nt > 1 ){
11085          if( key == '<' ){ nn--; if( nn <  0 ) nn = nt-1; }
11086          else               { nn++; if( nn >= nt) nn = 0   ; }
11087 #if 1
11088          ISQ_redisplay( seq , nn , isqDR_display ) ;
11089 #else
11090          ISQ_set_image_number( seq , nn ) ;
11091 #endif
11092        }
11093        busy=0; RETURN(1) ;
11094      }
11095      break ;
11096 
11097      
11098 
11099      case 'z':
11100      case 'Z':{
11101        int call=0 , zlev=seq->zoom_fac ;
11102        if( key == 'z' && zlev > ZOOM_BOT ){
11103          AV_assign_ival( seq->zoom_val_av , zlev-1 ) ; call = 1 ;
11104        } else if( key == 'Z' && zlev < ZOOM_TOP ){
11105          AV_assign_ival( seq->zoom_val_av , zlev+1 ) ; call = 1 ;
11106        }
11107        if( call )
11108          ISQ_zoom_av_CB( seq->zoom_val_av , (XtPointer)seq ) ;
11109        else
11110          XBell(seq->dc->display,100) ;
11111        busy=0; RETURN(1) ;
11112      }
11113      break ;
11114 
11115      
11116 
11117      case 'P':
11118      case 'p':{
11119        if( seq->zoom_fac > 1 )
11120          ISQ_zoom_pb_CB( seq->zoom_drag_pb , (XtPointer)seq , NULL ) ;
11121        else
11122          XBell(seq->dc->display,100) ;
11123        busy=0; RETURN(1) ;
11124      }
11125      break ;
11126 
11127      
11128 
11129      case 'c':
11130      case 'C':{
11131        ISQ_crop_pb_CB( seq->crop_drag_pb , (XtPointer)seq , NULL ) ;
11132        busy=0; RETURN(1) ;
11133      }
11134      break ;
11135 
11136            
11137 
11138      case 'i':
11139      case 'I':{
11140        int iv = seq->arrow[NARR_FRAC]->ival ;
11141        if( key == 'i' )
11142          AV_assign_ival( seq->arrow[NARR_FRAC] , iv-1 ) ;
11143        else if( key == 'I' )
11144          AV_assign_ival( seq->arrow[NARR_FRAC] , iv+1 ) ;
11145        ISQ_arrow_CB( seq->arrow[NARR_FRAC] , seq ) ;
11146        busy=0; RETURN(1) ;
11147      }
11148      break ;
11149 
11150    } 
11151 
11152    busy=0; RETURN(0);
11153 }
11154 
11155 
11156 
11157 
11158 
11159 
11160 
11161 void mri_rgb_transform_nD( MRI_IMAGE *im, int ndim, generic_func *tfunc )
11162 {
11163    MRI_IMAGE *flim , *shim ;
11164    byte  *iar ;
11165    float *sar , *far ;
11166    int ii , nvox , rr,gg,bb ;
11167    float fac , smax,fmax,fsrat ;
11168 
11169 ENTRY("mri_rgb_transform_nD") ;
11170 
11171    if( im    == NULL || im->kind != MRI_rgb     ) EXRETURN ;  
11172    if( tfunc == NULL || (ndim !=0 && ndim != 2) ) EXRETURN ;  
11173 
11174    flim = mri_to_float( im ) ;              
11175    fmax = mri_max( flim ) ;
11176    if( fmax == 0.0 ){ mri_free(flim); EXRETURN; }  
11177 
11178    shim = mri_copy( flim ) ;        
11179 
11180    switch( ndim ){               
11181      case 0:
11182        AFNI_CALL_0D_function( tfunc , shim->nvox , MRI_FLOAT_PTR(shim) ) ;
11183      break ;
11184 
11185      case 2:
11186        AFNI_CALL_2D_function( tfunc ,
11187                               shim->nx , shim->ny ,
11188                               shim->dx , shim->dy , MRI_FLOAT_PTR(shim) ) ;
11189      break ;
11190    }
11191 
11192    
11193 
11194    smax = mri_max(shim) ;
11195    if( smax == 0.0 ){ mri_free(flim); mri_free(shim); EXRETURN; }
11196    fsrat = fmax / smax ;
11197 
11198    iar = MRI_BYTE_PTR(im) ;
11199    far = MRI_FLOAT_PTR(flim) ; sar = MRI_FLOAT_PTR(shim) ;
11200 
11201    
11202 
11203 
11204    nvox = im->nvox ;
11205    for( ii=0 ; ii < nvox ; ii++ ){
11206      if( far[ii] <= 0.0 || sar[ii] <= 0.0 ){       
11207        iar[3*ii] = iar[3*ii+1] = iar[3*ii+2] = 0 ;
11208      } else {
11209        fac = fsrat * sar[ii] / far[ii] ; 
11210        rr  = fac * iar[3*ii]   ; iar[3*ii  ] = (rr > 255) ? 255 : rr ;
11211        gg  = fac * iar[3*ii+1] ; iar[3*ii+1] = (gg > 255) ? 255 : gg ;
11212        bb  = fac * iar[3*ii+2] ; iar[3*ii+2] = (bb > 255) ? 255 : bb ;
11213      }
11214    }
11215 
11216    mri_free(flim) ; mri_free(shim) ;  
11217    EXRETURN ;
11218 }
11219 
11220 
11221 
11222 
11223 void ISQ_save_jpeg( MCW_imseq *seq , char *fname )
11224 {
11225    MRI_IMAGE *tim , *flim ;
11226    char fn[288], filt[512] ;
11227    FILE *fp ;
11228    int sll ;
11229 
11230 ENTRY("ISQ_save_jpeg") ;
11231 
11232    if( !ISQ_REALZ(seq) || fname == NULL || ppmto_jpg95_filter == NULL ) EXRETURN;
11233 
11234    sll = strlen(fname) ; if( sll < 1 || sll > 255 ) EXRETURN ;
11235 
11236    reload_DC_colordef( seq->dc ) ;
11237    tim = XImage_to_mri( seq->dc, seq->given_xim, X2M_USE_CMAP | X2M_FORCE_RGB );
11238    if( tim == NULL ) EXRETURN ;
11239 
11240 
11241 
11242    if( AFNI_yesenv("AFNI_IMAGE_SAVESQUARE") ){
11243      tim->dx = seq->last_dx ; tim->dy = seq->last_dy ;
11244      flim = mri_squareaspect( tim ) ;
11245      if( flim != NULL ){ mri_free(tim); tim = flim; }
11246    }
11247 
11248 
11249 
11250    if( seq->zoom_fac > 1 && seq->mont_nx == 1 && seq->mont_ny == 1 ){
11251      flim = mri_dup2D(seq->zoom_fac,tim) ;
11252      if( flim != NULL ){ mri_free(tim); tim = flim; }
11253    }
11254 
11255 
11256 
11257    if( seq->mplot != NULL )
11258      memplot_to_RGB_sef( tim, seq->mplot, 0,0,MEMPLOT_FREE_ASPECT ) ;
11259 
11260 
11261 
11262    if( seq->zoom_fac >  1               &&
11263        seq->mont_nx  == 1               &&
11264        seq->mont_ny  == 1               &&
11265        AFNI_yesenv("AFNI_CROP_ZOOMSAVE")  ) {
11266 
11267       int xa,ya , iw=tim->nx/seq->zoom_fac , ih=tim->ny/seq->zoom_fac ;
11268 
11269       xa = seq->zoom_hor_off * tim->nx ;
11270       if( xa+iw > tim->nx ) xa = tim->nx-iw ;
11271       ya = seq->zoom_ver_off * tim->nx ;
11272       if( ya+ih > tim->ny ) ya = tim->ny-ih ;
11273       flim = mri_cut_2D( tim , xa,xa+iw-1 , ya,ya+ih-1 ) ;
11274       if( flim != NULL ){ mri_free(tim); tim = flim; }
11275    }
11276 
11277 
11278 
11279    strcpy(fn,fname) ;
11280    if( !STRING_HAS_SUFFIX(fname,".jpg") && !STRING_HAS_SUFFIX(fname,".JPG") )
11281      strcat(fn,".jpg") ;
11282 
11283    sprintf( filt , ppmto_jpg95_filter , fn ) ;
11284    INFO_message("Writing one %dx%d image to file %s",tim->nx,tim->ny,fn) ;
11285    signal( SIGPIPE , SIG_IGN ) ; errno = 0 ;
11286    fp = popen( filt , "w" ) ;
11287    if( fp == NULL ){
11288      ERROR_message("Can't open output filter: %s",filt) ;
11289      if( errno != 0 ) perror("** Unix error message") ;
11290      mri_free(tim) ; EXRETURN ;
11291    }
11292 
11293 
11294 
11295    fprintf(fp,"P6\n%d %d\n255\n" , tim->nx,tim->ny ) ;
11296    fwrite( MRI_RGB_PTR(tim), sizeof(byte), 3*tim->nvox, fp ) ;
11297    errno = 0 ; sll = pclose(fp) ;
11298    if( sll == -1 ){
11299      ERROR_message("JPEG Filter command was %s\n",filt) ;
11300      if( errno != 0 ) perror("** Unix error in image output pipe") ;
11301    }
11302 
11303    mri_free(tim) ; EXRETURN ;
11304 }