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 }