00001
00002
00003
00004
00005
00006
00007 #include "display.h"
00008 #include "mrilib.h"
00009
00010 static char * x11_vcl[] = { "StaticGray" , "GrayScale" , "StaticColor" ,
00011 "PseudoColor" , "TrueColor" , "DirectColor" } ;
00012
00013 MCW_DC *first_dc = NULL ;
00014
00015
00016
00017
00018
00019
00020 static int highbit(unsigned long ul)
00021 {
00022 int i; unsigned long hb;
00023
00024 hb = 0x80; hb = hb << 24;
00025 for (i=31; ((ul & hb) == 0) && i>=0; i--, ul<<=1);
00026 return i;
00027 }
00028
00029
00030
00031
00032
00033
00034 static void setup_byper( MCW_DC * dc )
00035 {
00036 XPixmapFormatValues * xpv ;
00037 int nxpv = 0 , ii ;
00038
00039 xpv = XListPixmapFormats( dc->display , &nxpv ) ;
00040
00041 if( xpv == NULL || nxpv == 0 ){
00042 dc->byper = dc->depth / 8 ; dc->bypad = 1 ;
00043 return ;
00044 }
00045
00046
00047
00048 for( ii=0 ; ii < nxpv ; ii++ ){
00049 if( xpv[ii].depth == dc->depth ){
00050 dc->byper = xpv[ii].bits_per_pixel / 8 ;
00051 dc->bypad = xpv[ii].scanline_pad / 8 ;
00052 XFree(xpv) ; return ;
00053 }
00054 }
00055
00056 dc->byper = dc->depth / 8 ; dc->bypad = 1 ;
00057 XFree(xpv) ; return ;
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 static MCW_DCOV * only_ovc = NULL ;
00079
00080 MCW_DC * MCW_new_DC( Widget wid , int ncol ,
00081 int novr , char * covr[] , char * lovr[] ,
00082 double gam , int newcmap )
00083 {
00084 MCW_DC * dc ;
00085 int ok , ii , new_ovc ;
00086 unsigned int nplmsk = 0 ;
00087 unsigned long plane_masks[1] ;
00088
00089 ENTRY("MCW_new_DC") ;
00090
00091 if( ncol < 4 || novr < 0 || ncol > MAX_COLORS || novr > MAX_COLORS ){
00092 fprintf(stderr,"\n*** MCW_new_DC: ILLEGAL number of colors: %d %d\n",ncol,novr) ;
00093 ncol = 4 ; novr = 0 ;
00094 }
00095
00096 dc = myXtNew(MCW_DC) ;
00097
00098 dc->appcontext = XtWidgetToApplicationContext( wid ) ;
00099 dc->display = XtDisplay( wid ) ;
00100 dc->screen = XtScreen( wid ) ;
00101 dc->screen_num = XScreenNumberOfScreen( dc->screen ) ;
00102 dc->visual = DefaultVisualOfScreen( dc->screen ) ;
00103 dc->origGC = DefaultGCOfScreen( dc->screen ) ;
00104 dc->planes = PlanesOfScreen( dc->screen ) ;
00105 dc->depth = DefaultDepthOfScreen( dc->screen ) ;
00106
00107 dc->cdef = NULL ;
00108
00109 setup_byper(dc) ;
00110
00111 dc->default_colormap = DefaultColormapOfScreen( dc->screen ) ;
00112
00113 dc->colormap = DefaultColormapOfScreen( dc->screen ) ;
00114
00115 dc->parent_widget = wid ;
00116
00117 dc->does_backingstore = DoesBackingStore(dc->screen) ;
00118 dc->does_saveunders = DoesSaveUnders(dc->screen) ;
00119
00120
00121
00122 { XVisualInfo vinfo , * vinfo_list ;
00123 int count ;
00124
00125 dc->visual_id = XVisualIDFromVisual( dc->visual ) ;
00126 vinfo.visualid = dc->visual_id ;
00127 vinfo_list = XGetVisualInfo(dc->display,VisualIDMask,&vinfo,&count) ;
00128 if( count > 0 && vinfo_list != NULL ){
00129 dc->visual_info = vinfo_list ;
00130 dc->visual_redmask = dc->visual_info->red_mask ;
00131 dc->visual_greenmask = dc->visual_info->green_mask ;
00132 dc->visual_bluemask = dc->visual_info->blue_mask ;
00133 dc->visual_redshift = 7 - highbit(dc->visual_redmask) ;
00134 dc->visual_greenshift = 7 - highbit(dc->visual_greenmask) ;
00135 dc->visual_blueshift = 7 - highbit(dc->visual_bluemask) ;
00136 #if defined(__cplusplus) || defined(c_plusplus)
00137 dc->visual_class = dc->visual_info->c_class ;
00138 #else
00139 dc->visual_class = dc->visual_info->class ;
00140 #endif
00141 if( dc->visual_class != PseudoColor &&
00142 dc->visual_class != TrueColor ){
00143
00144 fprintf(stderr,"\n\n"
00145 " ** The default X11 visual type on your computer is set to %s.\n"
00146 " ** AFNI programs only work with PseudoColor or TrueColor visuals.\n"
00147 " ** You must have your superuser modify your system's setup.\a\n" ,
00148 x11_vcl[dc->visual_class] ) ;
00149
00150 dc->visual_class = PseudoColor ;
00151 }
00152
00153 #if 0
00154 if( dc->visual_class == TrueColor ){
00155 static int done = 0 ;
00156 if( !done )
00157 fprintf(stderr,
00158 "\n"
00159 " ** The default X11 visual type on your computer is %d bit TrueColor.\n"
00160 " ** Support for this is experimental. AFNI was developed to use 4..12\n"
00161 " ** bit PseudoColor visuals for image display -- RW Cox, 22 Aug 1998.\n" ,
00162 dc->depth ) ;
00163 done = 1 ;
00164 }
00165 #endif
00166
00167 #if 0
00168 fprintf(stderr,"\n"
00169 "DC: redmask=%lx greenmask=%lx bluemask=%lx\n"
00170 " redshift=%d greenshift=%d blueshift=%d\n"
00171 " class=%d=%s depth=%d\n",
00172 dc->visual_redmask , dc->visual_greenmask , dc->visual_bluemask ,
00173 dc->visual_redshift , dc->visual_greenshift , dc->visual_blueshift ,
00174 dc->visual_class , x11_vcl[dc->visual_class] , dc->depth ) ;
00175 #endif
00176
00177 } else {
00178 dc->visual_info = NULL ;
00179 dc->visual_class = PseudoColor ;
00180 }
00181 }
00182
00183 #if 0
00184 { long reqmax ;
00185 reqmax = XMaxRequestSize(dc->display) ;
00186 printf("max X11 request size = %d\n",reqmax) ;
00187 }
00188 #endif
00189
00190 #define DEPTH_BOT 4
00191 #define DEPTH_TOP 32
00192
00193 if( dc->depth < DEPTH_BOT || dc->depth > DEPTH_TOP ){
00194 fprintf(stderr,"\n\n"
00195 " ** Your X11 display is set to %d bitplanes for image display.\n"
00196 " ** AFNI programs can only deal with between %d and %d bitplanes.\n"
00197 " ** You must have your superuser modify your system's setup.\a\n" ,
00198 dc->depth , DEPTH_BOT , DEPTH_TOP ) ;
00199 exit(1) ;
00200 }
00201
00202 dc->width = WidthOfScreen( dc->screen ) ;
00203 dc->height = HeightOfScreen( dc->screen ) ;
00204
00205 dc->ncol_im = ncol ;
00206 dc->gamma = dc->gamma_init = gam ;
00207
00208 if( dc->visual_class == PseudoColor ){
00209
00210 if( newcmap ){
00211 int ncold , cc ;
00212 XColor xcold ;
00213
00214
00215
00216 dc->colormap = XCreateColormap( dc->display , RootWindowOfScreen(dc->screen) ,
00217 dc->visual , AllocNone ) ;
00218
00219
00220
00221 #define NREUSE 9
00222 ncold = dc->visual_info->colormap_size ;
00223 if( ncold > NREUSE ) ncold = NREUSE ;
00224 for( cc=0 ; cc < ncold ; cc++ ){
00225 xcold.pixel = cc ;
00226 XQueryColors( dc->display , dc->default_colormap , &xcold , 1 ) ;
00227 XAllocColor( dc->display , dc->colormap , &xcold ) ;
00228 }
00229 }
00230
00231 ok = XAllocColorCells( dc->display , dc->colormap ,
00232 True , plane_masks , nplmsk ,
00233 dc->pix_im , dc->ncol_im ) ;
00234
00235 if( ! ok ){
00236 fprintf(stderr,
00237 "\a\n** XAllocColorCells fails for %d colors\n",dc->ncol_im) ;
00238 fprintf(stderr,
00239 "\n** try the -ncolor option to reduce # of colors\n");
00240 exit(1) ;
00241 }
00242
00243 dc->pix_im_ready = 1 ;
00244 } else if( dc->visual_class == TrueColor ){
00245 dc->pix_im_ready = 0 ;
00246 }
00247
00248 DC_init_im_col( dc ) ;
00249 DC_init_im_gry( dc ) ;
00250
00251 dc->use_xcol_im = False ;
00252 DC_set_image_colors( dc ) ;
00253
00254
00255
00256
00257
00258
00259
00260 new_ovc = 0 ;
00261 if( only_ovc == NULL ){ only_ovc = myXtNew(MCW_DCOV) ; new_ovc = 1 ; }
00262 dc->ovc = only_ovc ;
00263
00264 if( new_ovc ){
00265 only_ovc->xcol_ov[0] = dc->xgry_im[0] ;
00266 only_ovc->pix_ov[0] = dc->pix_im[0] ;
00267 only_ovc->name_ov[0] = XtNewString("none") ;
00268 only_ovc->label_ov[0] = only_ovc->name_ov[0] ;
00269 only_ovc->ncol_ov = 1 ;
00270
00271 only_ovc->bright_ov[0] = 0.0 ;
00272
00273 dc->ovc->r_ov[0] = 0 ;
00274 dc->ovc->g_ov[0] = 0 ;
00275 dc->ovc->b_ov[0] = 0 ;
00276 }
00277
00278 for( ii=0 ; ii < novr ; ii++ ){
00279
00280 ok = DC_add_overlay_color( dc , covr[ii] , lovr[ii] ) ;
00281
00282 if( ok < 0 )
00283 fprintf(stderr,
00284 "\n*** can't get X11 colormap entry for overlay color %s" , lovr[ii] ) ;
00285 #ifdef DISPLAY_DEBUG
00286 else {
00287 printf("\n*** overlay color %s has pixel %d at index %d" ,
00288 dc->ovc->name_ov[ok] , (int)dc->ovc->pix_ov[ok] , ok ) ;
00289 fflush(stdout) ;
00290 }
00291 #endif
00292 }
00293 OVC_mostest( dc->ovc ) ;
00294
00295
00296
00297 { XGCValues gcv;
00298 int ifont ;
00299 XFontStruct * mfinfo = NULL ;
00300 char * xdef ;
00301
00302 gcv.function = GXcopy ;
00303 dc->myGC = XCreateGC( dc->display,
00304 RootWindowOfScreen(dc->screen) ,
00305 GCFunction , &gcv ) ;
00306
00307 xdef = XGetDefault(dc->display,"AFNI","gfont") ;
00308 if( xdef != NULL )
00309 mfinfo = XLoadQueryFont(dc->display,xdef) ;
00310
00311 if( mfinfo == NULL ){
00312 for( ifont=0 ; tfont_hopefuls[ifont] != NULL ; ifont++ ){
00313 mfinfo = XLoadQueryFont(dc->display, tfont_hopefuls[ifont]) ;
00314 if( mfinfo != NULL ) break ;
00315 }
00316 }
00317 if( mfinfo == NULL ){
00318 fprintf(stderr,
00319 "\n*** Cannot load any text fonts in display.c ***\n" ) ;
00320 } else {
00321 XSetFont( dc->display , dc->myGC , mfinfo->fid ) ;
00322 }
00323 XSetForeground(dc->display , dc->myGC , dc->ovc->pixov_darkest ) ;
00324 XSetBackground(dc->display , dc->myGC , dc->ovc->pixov_brightest ) ;
00325 dc->myFontStruct = mfinfo ;
00326 }
00327
00328 dc->parent = dc->aux = NULL ;
00329
00330 #ifdef DISPLAY_DEBUG
00331 printf("\n") ;
00332 #endif
00333
00334 #if 0
00335 reload_DC_colordef( dc ) ;
00336 #else
00337 dc->cdef = NULL ;
00338 #endif
00339
00340 if( first_dc == NULL ) first_dc = dc ;
00341
00342 RETURN(dc) ;
00343 }
00344
00345
00346
00347
00348
00349 void DC_palette_setgray( MCW_DC * dc )
00350 {
00351 dc->use_xcol_im = False ;
00352 DC_set_image_colors( dc ) ;
00353 return ;
00354 }
00355
00356
00357
00358
00359
00360 void DC_palette_setcolor( MCW_DC * dc )
00361 {
00362 dc->use_xcol_im = True ;
00363 DC_set_image_colors( dc ) ;
00364 return ;
00365 }
00366
00367
00368
00369
00370
00371 void DC_palette_restore( MCW_DC * dc , double new_gamma )
00372 {
00373 dc->gamma = (new_gamma > 0 ) ? new_gamma : dc->gamma_init ;
00374 DC_init_im_col( dc ) ;
00375 DC_init_im_gry( dc ) ;
00376 DC_set_image_colors( dc ) ;
00377 }
00378
00379
00380
00381
00382
00383
00384 static double mypow( double x , double y )
00385 {
00386 double b ;
00387 if( x <= 0.0 ) return 0.0 ;
00388 if( y == 1.0 ) return x ;
00389 b = log(x) ; b = exp( y*b ) ;
00390 return b ;
00391 }
00392
00393 void DC_init_im_gry( MCW_DC * dc )
00394 {
00395 int i, k, m, nc ;
00396 float a , gamm , b ;
00397
00398 char * env ;
00399 float atop=255.0 , abot=55.0 ;
00400
00401 #if 0
00402 env = getenv("AFNI_GRAYSCALE_TOP") ;
00403 if( env != NULL ){
00404 float val = strtod(env,NULL) ;
00405 if( val <= 255.0 && val >= 100.0 ) atop = val ;
00406 }
00407 #endif
00408
00409 env = getenv("AFNI_GRAYSCALE_BOT") ;
00410 if( env != NULL ){
00411 float val = strtod(env,NULL) ;
00412 if( val < atop && val >= 0.0 ) abot = val ;
00413 }
00414
00415 nc = dc->ncol_im ;
00416 gamm = dc->gamma ;
00417 a = (atop-abot) / nc ;
00418
00419 for (i=0; i < nc ; i++) {
00420 b = log( (a*i+abot)/255.0 ) ;
00421 b = exp( gamm * b ) ;
00422 k = (int)( 255.0 * b + 0.5 ) ;
00423
00424 m = BYTE_TO_INTEN(k) ;
00425
00426 dc->xint_im[i] = m ;
00427 dc->xgry_im[i].red = m ;
00428 dc->xgry_im[i].green = m ;
00429 dc->xgry_im[i].blue = m ;
00430 dc->xgry_im[i].flags = DoRed|DoGreen|DoBlue;
00431
00432 if( dc->visual_class == PseudoColor )
00433 dc->xgry_im[i].pixel = dc->pix_im[i];
00434 }
00435
00436 return ;
00437 }
00438
00439
00440
00441
00442
00443
00444 rgbyte DC_spectrum_ZSS( double an , double gamm )
00445 {
00446 int r,g,b , m ;
00447 rgbyte color ;
00448
00449 if( gamm <= 0.0 ) gamm = 1.0 ;
00450
00451 while( an < 0.0 ) an += 360.0 ;
00452 while( an > 360.0 ) an -= 360.0 ;
00453
00454 an = an / 90.0 ;
00455
00456 if( an <= 1.0 ){
00457 r = 255.*mypow(1.0-an,gamm)+0.5 ;
00458 g = 255.*mypow(0.5*an,gamm)+0.5 ;
00459 b = 255.*mypow(an ,gamm)+0.5 ;
00460 } else if( an <= 2.0 ){
00461 r = 0 ;
00462 g = 255.*mypow(0.5*an,gamm)+0.5 ;
00463 b = 255.*mypow(2.0-an,gamm)+0.5 ;
00464 } else if( an <= 3.0 ){
00465 r = 255.*mypow(an-2.0,gamm)+0.5 ;
00466 g = 255 ;
00467 b = 0 ;
00468 } else {
00469 r = 255 ;
00470 g = 255.*mypow(4.0-an,gamm)+0.5 ;
00471 b = 0 ;
00472 }
00473
00474 #if 0
00475 m = MAX(r,g) ; m = MAX(m,b) ;
00476 if( m < 255 ){ float s=255.0/m; r *= s; g *= s; b *= s; }
00477 #endif
00478
00479 color.r = r ; color.g = g ; color.b = b ; return color ;
00480 }
00481
00482
00483
00484
00485
00486
00487 rgbyte DC_spectrum_AJJ( double an , double gamm )
00488 {
00489 int r,g,b , m ;
00490 double ak,ab,s,c,sb,cb ;
00491 rgbyte color ;
00492
00493 if( gamm <= 0.0 ) gamm = 1.0 ;
00494
00495 #if 0
00496 ak = 105.; s = 255.0-ak; c = s /60.;
00497 ab = 65.; sb = 255.0-ab; cb = sb/60.;
00498 #else
00499 ak = 5.; s = 255.0-ak; c = s /60.;
00500 ab = 5.; sb = 255.0-ab; cb = sb/60.;
00501 #endif
00502
00503 while( an < 0.0 ) an += 360.0 ;
00504 while( an > 360.0 ) an -= 360.0 ;
00505
00506 if( an < 120. ){
00507 r = 255.*mypow((ak + MIN(s,(120. - an)*c))/255., gamm) +.5;
00508 g = 255.*mypow((ak + MIN(s,an*c))/255., gamm) +.5;
00509 m = MAX(r,g) ;
00510 b = 0;
00511 } else if( an < 240. ){
00512 r = 0;
00513 g = 255.*mypow((ak + MIN(s ,(240. - an)*c ))/255., gamm) +.5;
00514 b = 255.*mypow((ab + MIN(sb,(an - 120.)*cb))/255., gamm) +.5;
00515 m = MAX(g,b) ;
00516 } else {
00517 r = 255.*mypow((ak + MIN(s,(an - 240.)*c ))/255., gamm) +.5;
00518 g = 0;
00519 b = 255.*mypow((ab + MIN(s,(360. - an)*cb))/255., gamm) +.5;
00520 m = MAX(r,b) ;
00521 }
00522
00523 #if 0
00524 if( m < 255 ){ s = 255.0/m ; r *= s ; g *= s ; b *= s ; }
00525 #endif
00526
00527 color.r = r ; color.g = g ; color.b = b ; return color ;
00528 }
00529
00530
00531
00532
00533
00534
00535 void DC_init_im_col( MCW_DC * dc )
00536 {
00537 double da, an, c, s, sb, cb, ak, ab , a1,a2 , gamm ;
00538 int i, r, g, b , nc ;
00539
00540 a1 = 0.0 ;
00541 a2 = 240.0 ;
00542
00543 nc = dc->ncol_im ;
00544 gamm = dc->gamma ;
00545
00546 ak = 105.; s = 150.; c = s/60.;
00547 ab = 65.; sb = 190.; cb = s/60.;
00548
00549 an = a1; da = (a2 - a1)/nc ; an = an-da+360.;
00550
00551 for( i=0 ; i < nc ; i++ ){
00552
00553 an += da; an = fmod(an,360.);
00554
00555 if((an >= 0) && (an < 120.)) {
00556 r = 255.*mypow((ak + MIN(s,(120. - an)*c))/255., gamm) +.5;
00557 g = 255.*mypow((ak + MIN(s,an*c))/255., gamm) +.5;
00558 b = 0;
00559 } else if((an >= 120.) && (an < 240.)) {
00560 r = 0;
00561 g = 255.*mypow((ak + MIN(s ,(240. - an)*c))/255., gamm) +.5;
00562 b = 255.*mypow((ab + MIN(sb,(an - 120.)*cb))/255., gamm) +.5;
00563 } else if(an >= 240.) {
00564 r = 255.*mypow((ak + MIN(s,(an - 240.)*c))/255., gamm) +.5;
00565 g = 0;
00566 b = 255.*mypow((ak + MIN(s,(360. - an)*c))/255., gamm) +.5;
00567 }
00568 dc->xcol_im[i].red = BYTE_TO_INTEN(r) ;
00569 dc->xcol_im[i].green = BYTE_TO_INTEN(g) ;
00570 dc->xcol_im[i].blue = BYTE_TO_INTEN(b) ;
00571 dc->xcol_im[i].flags = DoRed|DoGreen|DoBlue;
00572
00573 if( dc->visual_class == PseudoColor )
00574 dc->xcol_im[i].pixel = dc->pix_im[i];
00575 }
00576 return ;
00577 }
00578
00579 #if 0
00580
00581
00582
00583
00584 Pixel RGB_byte_to_color( MCW_DC * dc , int r , int g , int b )
00585 {
00586 XColor any_col;
00587
00588 any_col.red = BYTE_TO_INTEN(r);
00589 any_col.green = BYTE_TO_INTEN(g);
00590 any_col.blue = BYTE_TO_INTEN(b);
00591 any_col.flags = DoRed | DoGreen | DoBlue;
00592 XAllocColor( dc->display , dc->colormap , &any_col );
00593 return any_col.pixel ;
00594 }
00595
00596
00597
00598
00599
00600 Pixel Name_to_color( MCW_DC * dc , char * name )
00601 {
00602 XColor cell , exact ;
00603 int ok ;
00604
00605 ok = XAllocNamedColor( dc->display , dc->colormap , name , &cell , &exact ) ;
00606
00607 if( ok ) return cell.pixel ;
00608 else return BlackPixelOfScreen( dc->screen ) ;
00609 }
00610 #endif
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 int DC_add_overlay_color( MCW_DC * dc , char * name , char * label )
00621 {
00622 int ii , ok , newcol ;
00623 Pixel newpix ;
00624 XColor cell ;
00625
00626 ENTRY("DC_add_overlay_color") ;
00627
00628 if( name == NULL || strlen(name) == 0 ) RETURN(-1) ;
00629 if( label == NULL ) label = name ;
00630
00631
00632
00633 for( ii=1 ; ii < dc->ovc->ncol_ov ; ii++ )
00634 if( strcmp(label,dc->ovc->label_ov[ii]) == 0 ) break ;
00635
00636 newcol = (ii == dc->ovc->ncol_ov) ;
00637 if( ii == dc->ovc->ncol_ov ){
00638 unsigned int nplmsk = 0 ;
00639 unsigned long plane_masks[1] ;
00640
00641 if( ii >= MAX_COLORS ) RETURN(-1) ;
00642
00643 if( dc->visual_class == PseudoColor ){
00644 ok = XAllocColorCells( dc->display , dc->colormap ,
00645 True , plane_masks , nplmsk , &newpix , 1 ) ;
00646 if( !ok ) RETURN(-1) ;
00647 cell.pixel = newpix ;
00648 }
00649
00650 } else {
00651
00652 if( strcmp(name,dc->ovc->name_ov[ii]) == 0 ) RETURN(ii) ;
00653
00654 if( dc->visual_class == PseudoColor )
00655 cell.pixel = dc->ovc->pix_ov[ii] ;
00656 else if( dc->visual_class == TrueColor )
00657 XFreeColors( dc->display, dc->colormap, dc->ovc->pix_ov+ii, 1, 0 ) ;
00658 }
00659
00660 ok = XParseColor( dc->display , dc->colormap , name, &cell ) ;
00661 if( !ok ) RETURN(-1) ;
00662
00663 if( newcol ){
00664 dc->ovc->ncol_ov++ ;
00665 } else {
00666 myXtFree( dc->ovc->name_ov[ii] ) ;
00667 myXtFree( dc->ovc->label_ov[ii] ) ;
00668 }
00669
00670 if( dc->visual_class == PseudoColor )
00671 XStoreColor( dc->display , dc->colormap , &cell ) ;
00672 else if( dc->visual_class == TrueColor )
00673 XAllocColor( dc->display , dc->colormap , &cell ) ;
00674
00675 dc->ovc->xcol_ov[ii] = cell ;
00676 dc->ovc->pix_ov[ii] = cell.pixel ;
00677 dc->ovc->name_ov[ii] = XtNewString(name) ;
00678 dc->ovc->label_ov[ii] = XtNewString(label) ;
00679
00680 dc->ovc->r_ov[ii] = INTEN_TO_BYTE(cell.red) ;
00681 dc->ovc->g_ov[ii] = INTEN_TO_BYTE(cell.green) ;
00682 dc->ovc->b_ov[ii] = INTEN_TO_BYTE(cell.blue) ;
00683
00684 if( dc->visual_class == PseudoColor )
00685 FREE_DC_colordef(dc->cdef) ;
00686
00687 dc->ovc->bright_ov[ii] = BRIGHTNESS( DCOV_REDBYTE(dc,ii) ,
00688 DCOV_GREENBYTE(dc,ii) ,
00689 DCOV_BLUEBYTE(dc,ii) ) ;
00690 RETURN(ii) ;
00691 }
00692
00693
00694
00695 int DC_find_overlay_color( MCW_DC *dc , char *label )
00696 {
00697 int ii ;
00698 if( dc == NULL || label == NULL ) return -1 ;
00699 for( ii=0 ; ii < dc->ovc->ncol_ov ; ii++ )
00700 if( strcasecmp(label,dc->ovc->label_ov[ii]) == 0 ) return ii ;
00701 return -1 ;
00702 }
00703
00704
00705
00706 int DC_find_closest_overlay_color( MCW_DC *dc , char *cname )
00707 {
00708 float rr,gg,bb ; int b_rr,b_gg,b_bb ;
00709 int ii , jj;
00710
00711 if( dc == NULL || cname == NULL || *cname == '\0' ) return -1 ;
00712
00713 ii = DC_find_overlay_color( dc , cname ) ;
00714 if( ii >= 0 ) return ii ;
00715
00716 ii = DC_parse_color( dc, cname, &rr,&gg,&bb ) ;
00717 if( ii ) return -1 ;
00718
00719 b_rr = (int)(255.9*rr) ;
00720 b_gg = (int)(255.9*gg) ;
00721 b_bb = (int)(255.9*bb) ;
00722
00723 jj = 0 ; rr = 9999999.9 ;
00724 for( ii=0 ; ii < dc->ovc->ncol_ov ; ii++ ){
00725 gg = abs(b_rr-(int)dc->ovc->r_ov[ii])
00726 +abs(b_gg-(int)dc->ovc->g_ov[ii])
00727 +abs(b_bb-(int)dc->ovc->b_ov[ii]) ;
00728 if( gg < rr ){ jj = ii ; rr = gg ; }
00729 }
00730
00731 return jj ;
00732 }
00733
00734
00735
00736
00737
00738
00739 static unsigned short tmp1[MAX_COLORS] , tmp2[MAX_COLORS] , tmp3[MAX_COLORS] ;
00740 static int tmpi[MAX_COLORS] ;
00741
00742 void load_tmp_colors( int nc , XColor *ccc )
00743 {
00744 register int i ;
00745
00746 for( i=0 ; i < nc ; i++ ){
00747 tmp1[i] = ccc[i].red ;
00748 tmp2[i] = ccc[i].green ;
00749 tmp3[i] = ccc[i].blue ;
00750 }
00751 return ;
00752 }
00753
00754
00755
00756
00757
00758 void DC_palette_rotate( MCW_DC * dc , int kk )
00759 {
00760 register int i , j , nc , k ;
00761 XColor * xc ;
00762
00763 nc = dc->ncol_im ;
00764
00765 if( dc->use_xcol_im ){
00766 xc = & ( dc->xcol_im[0] ) ;
00767 k = -kk ;
00768 } else {
00769 xc = & ( dc->xgry_im[0] ) ;
00770 k = -kk ;
00771 }
00772
00773 load_tmp_colors( nc , xc ) ;
00774
00775 for( i=0 ; i < nc ; i++ ){
00776 j = (i+nc+k) % nc ;
00777
00778 xc[i].red = tmp1[j] ;
00779 xc[i].green = tmp2[j] ;
00780 xc[i].blue = tmp3[j] ;
00781 }
00782
00783 if( ! dc->use_xcol_im ){
00784 for( i=0 ; i < nc ; i++ ) tmpi[i] = dc->xint_im[i] ;
00785 for( i=0 ; i < nc ; i++ ) dc->xint_im[i] = tmpi[(i+nc+k)%nc] ;
00786 }
00787
00788 DC_set_image_colors( dc ) ;
00789 return ;
00790 }
00791
00792
00793
00794 void DC_palette_swap( MCW_DC * dc )
00795 {
00796 register int i, k , nc ;
00797 XColor * xc ;
00798
00799 nc = dc->ncol_im ;
00800 k = nc - 1 ;
00801
00802 if( dc->use_xcol_im ){
00803 xc = & ( dc->xcol_im[0] ) ;
00804 } else {
00805 xc = & ( dc->xgry_im[0] ) ;
00806 }
00807
00808 load_tmp_colors( nc , xc ) ;
00809
00810 for(i=0; i < nc ; i++) {
00811 xc[i].red = tmp1[k-i];
00812 xc[i].green = tmp2[k-i];
00813 xc[i].blue = tmp3[k-i];
00814 }
00815
00816 if( ! dc->use_xcol_im ){
00817 for( i=0 ; i < nc ; i++ ) tmpi[i] = dc->xint_im[i] ;
00818 for( i=0 ; i < nc ; i++ ) dc->xint_im[i] = tmpi[k-i] ;
00819 }
00820
00821 DC_set_image_colors( dc ) ;
00822 return ;
00823 }
00824
00825
00826
00827 void DC_palette_bright( MCW_DC * dc , int dd )
00828 {
00829 if( dc->use_xcol_im ) DC_color_bright( dc , dd ) ;
00830 else DC_gray_change( dc , -2*dd ) ;
00831 return;
00832 }
00833
00834
00835
00836 void DC_color_bright( MCW_DC * dc , int dlev )
00837 {
00838 register int i ;
00839 double c ;
00840 int nc = dc->ncol_im ;
00841 XColor * xc = dc->xcol_im ;
00842
00843 c = 1.0 - 0.005 * (double) dlev ;
00844
00845 for( i=0 ; i < nc ; i++ ){
00846 xc[i].red = CLIP_INTEN( c * xc[i].red ) ;
00847 xc[i].green = CLIP_INTEN( c * xc[i].green ) ;
00848 xc[i].blue = CLIP_INTEN( c * xc[i].blue ) ;
00849 }
00850 DC_set_image_colors( dc ) ;
00851 return ;
00852 }
00853
00854
00855
00856 void DC_gray_change( MCW_DC * dc , int dlev )
00857 {
00858 register int i, k, delta ;
00859 int nc = dc->ncol_im ;
00860 XColor * xc = dc->xgry_im ;
00861 int * in = dc->xint_im ;
00862
00863 if( dc->use_xcol_im ) return ;
00864
00865 delta = dlev * abs( (in[nc-1] - in[0]) / nc ) ;
00866
00867 for( i=0 ; i < nc ; i++ ){
00868 k = in[i] += delta ;
00869 xc[i].red = xc[i].green = xc[i].blue = CLIP_INTEN(k) ;
00870 }
00871 DC_set_image_colors( dc ) ;
00872 return ;
00873 }
00874
00875
00876
00877 void DC_palette_squeeze( MCW_DC * dc , int dd )
00878 {
00879 if( dc->use_xcol_im ) DC_color_squeeze( dc , dd ) ;
00880 else DC_gray_contrast( dc , -2*dd ) ;
00881 return;
00882 }
00883
00884
00885
00886 void DC_color_squeeze( MCW_DC * dc , int dlev )
00887 {
00888 return ;
00889 }
00890
00891
00892
00893 void DC_gray_contrast( MCW_DC * dc , int dlev )
00894 {
00895 register int i, k, delta ;
00896 int nc = dc->ncol_im ;
00897 XColor * xc = dc->xgry_im ;
00898 int * in = dc->xint_im ;
00899
00900 if( dc->use_xcol_im ) return ;
00901
00902 delta = dlev * (abs(in[nc-1] - in[0]) >> 6) / nc ;
00903 if( delta == 0 ) delta = dlev ;
00904
00905 for( i=0 ; i < nc ; i++ ){
00906 k = in[i] += i * delta ;
00907 xc[i].red = xc[i].green = xc[i].blue = CLIP_INTEN(k) ;
00908 }
00909 DC_set_image_colors( dc ) ;
00910 return ;
00911 }
00912
00913
00914
00915 void DC_gray_conbrio( MCW_DC *dc , int dlev )
00916 {
00917 register int i, k, bdelta,cdelta ;
00918 int nc = dc->ncol_im ;
00919 XColor * xc = dc->xgry_im ;
00920 int * in = dc->xint_im ;
00921
00922 if( dc->use_xcol_im ) return ;
00923
00924 bdelta = dlev * abs(in[nc-1] - in[0]) / nc ;
00925 cdelta = dlev * (abs(in[nc-1] - in[0]) >> 6) / nc ;
00926 if( cdelta == 0 ) cdelta = dlev ;
00927
00928 for( i=0 ; i < nc ; i++ ){
00929 k = in[i] += i * cdelta - bdelta ;
00930 xc[i].red = xc[i].green = xc[i].blue = CLIP_INTEN(k) ;
00931 }
00932 DC_set_image_colors( dc ) ;
00933 return ;
00934 }
00935
00936
00937
00938 Boolean MCW_check_iconsize( int width , int height , MCW_DC * dc )
00939 {
00940 int ii ;
00941 Boolean good ;
00942 int nsl = 0 ;
00943 XIconSize * xsl = NULL ;
00944
00945
00946
00947 if( width < 1 || height < 1 ) return False ;
00948
00949 XGetIconSizes( dc->display , RootWindowOfScreen(dc->screen) , &xsl , &nsl ) ;
00950
00951 if( xsl == NULL || nsl < 1 ) return True ;
00952
00953 good = False ;
00954
00955 for( ii=0 ; ii < nsl ; ii++ ){
00956
00957 if( width >= xsl[ii].min_width && width <= xsl[ii].max_width &&
00958 height >= xsl[ii].min_height && height <= xsl[ii].max_height &&
00959
00960 (width - xsl[ii].min_width ) % xsl[ii].width_inc == 0 &&
00961 (height - xsl[ii].min_height) % xsl[ii].height_inc == 0 ) { good = True ; break ; }
00962 }
00963
00964 XFree(xsl) ;
00965 return good ;
00966 }
00967
00968
00969
00970
00971
00972
00973
00974 XColor * DCpix_to_XColor( MCW_DC * dc , Pixel pp , int use_cmap )
00975 {
00976 XColor * ulc , * ovc ;
00977 int ii ;
00978
00979 if( use_cmap ){
00980 static XColor xc ;
00981 byte rr,gg,bb ;
00982
00983 DC_pixel_to_rgb( dc , pp , &rr,&gg,&bb ) ;
00984 xc.red = BYTE_TO_INTEN(rr) ;
00985 xc.green = BYTE_TO_INTEN(gg) ;
00986 xc.blue = BYTE_TO_INTEN(bb) ;
00987 return &xc ;
00988 }
00989
00990 ulc = (dc->use_xcol_im) ? dc->xcol_im : dc->xgry_im ;
00991 ovc = dc->ovc->xcol_ov ;
00992
00993 for( ii=0 ; ii < dc->ncol_im ; ii++ )
00994 if( pp == dc->pix_im[ii] ) return (ulc+ii) ;
00995
00996 for( ii=0 ; ii < dc->ovc->ncol_ov ; ii++ )
00997 if( pp == dc->ovc->pix_ov[ii] ) return (ovc+ii) ;
00998
00999 return ulc ;
01000 }
01001
01002
01003
01004 void DC_fg_color( MCW_DC * dc , int nov )
01005 {
01006 XSetForeground( dc->display , dc->myGC , dc->ovc->pix_ov[nov] ) ;
01007 return ;
01008 }
01009
01010 void DC_bg_color( MCW_DC * dc , int nov )
01011 {
01012 XSetBackground( dc->display , dc->myGC , dc->ovc->pix_ov[nov] ) ;
01013 return ;
01014 }
01015
01016 void DC_fg_colorpix( MCW_DC * dc , Pixel pix )
01017 {
01018 XSetForeground( dc->display , dc->myGC , pix ) ;
01019 return ;
01020 }
01021
01022 void DC_fg_colortext( MCW_DC * dc , char * cname )
01023 {
01024 XColor any_col , rgb_col ;
01025
01026 if( ! XAllocNamedColor( dc->display , dc->colormap ,
01027 cname , &any_col, &rgb_col ) ){
01028
01029 fprintf(stderr,"\n** XAllocNamedColor problem: %s **\n",cname ) ;
01030 } else {
01031 XSetForeground( dc->display , dc->myGC , any_col.pixel ) ;
01032 }
01033 return ;
01034 }
01035
01036 void DC_linewidth( MCW_DC * dc , int lw )
01037 {
01038 XGCValues gcv ;
01039
01040 if( lw >= 0 ){
01041 gcv.line_width = lw ;
01042 gcv.join_style = JoinBevel ;
01043 XChangeGC( dc->display , dc->myGC , GCLineWidth | GCJoinStyle , &gcv ) ;
01044 }
01045 return ;
01046 }
01047
01048 void DC_linestyle( MCW_DC * dc , int lw )
01049 {
01050 XGCValues gcv ;
01051 gcv.line_style = lw ;
01052 XChangeGC( dc->display , dc->myGC , GCLineStyle , &gcv ) ;
01053 return ;
01054 }
01055
01056
01057
01058
01059
01060
01061 void OVC_mostest( MCW_DCOV * ovc )
01062 {
01063 float bright_inten , dark_inten , red_inten , green_inten , blue_inten , inten ;
01064 int bright_ii , dark_ii , red_ii , green_ii , blue_ii ;
01065 float yellow_inten ;
01066 int yellow_ii ;
01067 int ii ;
01068
01069 if( ovc == NULL || ovc->ncol_ov < 2 ) return ;
01070
01071 bright_inten = dark_inten = XCOL_BRIGHTNESS( ovc->xcol_ov[1] ) ;
01072 bright_ii = dark_ii = 1 ;
01073
01074 red_inten = XCOL_REDNESS ( ovc->xcol_ov[1] ) ;
01075 green_inten = XCOL_GREENNESS( ovc->xcol_ov[1] ) ;
01076 blue_inten = XCOL_BLUENESS ( ovc->xcol_ov[1] ) ;
01077 red_ii = green_ii = blue_ii = 1 ;
01078
01079 yellow_ii = 1 ;
01080 yellow_inten = XCOL_YELLOWNESS( ovc->xcol_ov[1] ) ;
01081
01082 for( ii=2 ; ii < ovc->ncol_ov ; ii++ ){
01083 inten = XCOL_BRIGHTNESS( ovc->xcol_ov[ii] ) ;
01084 if( inten > bright_inten ){
01085 bright_inten = inten ; bright_ii = ii ;
01086 } else if( inten < dark_inten ){
01087 dark_inten = inten ; dark_ii = ii ;
01088 }
01089
01090 inten = XCOL_REDNESS( ovc->xcol_ov[ii] ) ;
01091 if( inten > red_inten ){
01092 red_inten = inten ; red_ii = ii ;
01093 }
01094
01095 inten = XCOL_GREENNESS( ovc->xcol_ov[ii] ) ;
01096 if( inten > green_inten ){
01097 green_inten = inten ; green_ii = ii ;
01098 }
01099
01100 inten = XCOL_BLUENESS( ovc->xcol_ov[ii] ) ;
01101 if( inten > blue_inten ){
01102 blue_inten = inten ; blue_ii = ii ;
01103 }
01104
01105 inten = XCOL_YELLOWNESS( ovc->xcol_ov[ii] ) ;
01106 if( inten > yellow_inten ){
01107 yellow_inten = inten ; yellow_ii = ii ;
01108 }
01109 }
01110 ovc->ov_brightest = bright_ii ; ovc->pixov_brightest = ovc->pix_ov[bright_ii] ;
01111 ovc->ov_darkest = dark_ii ; ovc->pixov_darkest = ovc->pix_ov[dark_ii] ;
01112 ovc->ov_reddest = red_ii ; ovc->pixov_reddest = ovc->pix_ov[red_ii] ;
01113 ovc->ov_greenest = green_ii ; ovc->pixov_greenest = ovc->pix_ov[green_ii] ;
01114 ovc->ov_bluest = blue_ii ; ovc->pixov_bluest = ovc->pix_ov[blue_ii] ;
01115 ovc->ov_yellowest = yellow_ii ; ovc->pixov_yellowest = ovc->pix_ov[yellow_ii] ;
01116 }
01117
01118
01119
01120
01121
01122
01123
01124
01125 void DC_set_image_colors( MCW_DC * dc )
01126 {
01127 int ii , nc ;
01128 XColor * xc ;
01129
01130 nc = dc->ncol_im ;
01131 xc = (dc->use_xcol_im) ? (dc->xcol_im) : (dc->xgry_im) ;
01132
01133 if( dc->visual_class == PseudoColor ){
01134
01135 XStoreColors( dc->display , dc->colormap , xc , nc ) ;
01136
01137 #if 0
01138 if( dc->cdef != NULL ) reload_DC_colordef( dc ) ;
01139 #else
01140
01141 #endif
01142
01143 } else if( dc->visual_class == TrueColor ){
01144
01145 for( ii=0 ; ii < nc ; ii++ ){
01146 if( dc->pix_im_ready )
01147 XFreeColors( dc->display, dc->colormap, dc->pix_im+ii, 1, 0 ) ;
01148
01149 XAllocColor( dc->display , dc->colormap , xc+ii ) ;
01150 dc->pix_im[ii] = xc[ii].pixel ;
01151 }
01152 dc->pix_im_ready = 1 ;
01153
01154 }
01155
01156
01157
01158 for( ii=0 ; ii < nc ; ii++ ){
01159 dc->r_im[ii] = INTEN_TO_BYTE( xc[ii].red ) ;
01160 dc->g_im[ii] = INTEN_TO_BYTE( xc[ii].green ) ;
01161 dc->b_im[ii] = INTEN_TO_BYTE( xc[ii].blue ) ;
01162 #if 0
01163 dc->gray_im[ii] = BRIGHTNESS( dc->r_im[ii] , dc->g_im[ii] , dc->b_im[ii] ) ;
01164 #endif
01165 }
01166
01167 return ;
01168 }
01169
01170
01171
01172
01173
01174 void DC_yokify( Widget w , MCW_DC * dc )
01175 {
01176 if( w == NULL || dc == NULL || !XtIsWidget(w) ) return ;
01177
01178 XtVaSetValues( w ,
01179 XmNvisual , dc->visual ,
01180 XmNcolormap , dc->colormap ,
01181 XmNdepth , dc->depth ,
01182 XmNscreen , dc->screen ,
01183 XmNbackground , 0 ,
01184 XmNborderColor , 0 ,
01185 NULL ) ;
01186 return ;
01187 }
01188
01189
01190
01191
01192
01193 void reload_DC_colordef( MCW_DC * dc )
01194 {
01195 XVisualInfo * vin ;
01196 DC_colordef * cd ;
01197
01198 ENTRY("reload_DC_colordef") ;
01199
01200
01201
01202 if( dc == NULL || dc->visual_info == NULL ){
01203 fprintf(stderr,"reload_DC_colordef: entry values are NULL\n") ;
01204 EXRETURN ;
01205 }
01206
01207 vin = dc->visual_info ;
01208
01209
01210
01211 #if defined(__cplusplus) || defined(c_plusplus)
01212 if( vin->c_class == PseudoColor ){
01213 #else
01214 if( vin->class == PseudoColor ){
01215 #endif
01216
01217 int iz , count , ii ;
01218 XColor * xcol ;
01219
01220
01221
01222 cd = (DC_colordef *) malloc( sizeof(DC_colordef) ) ;
01223 cd->classKRH = PseudoColor ;
01224 cd->depth = vin->depth ;
01225
01226
01227
01228 count = vin->colormap_size ;
01229 xcol = (XColor *) malloc( sizeof(XColor) * count ) ;
01230 for( ii=0 ; ii < count ; ii++ ) xcol[ii].pixel = ii ;
01231
01232 XQueryColors( dc->display , dc->colormap , xcol , count ) ;
01233
01234
01235
01236 cd->ncolors = count ;
01237 cd->rr = (byte *) malloc( count ) ;
01238 cd->gg = (byte *) malloc( count ) ;
01239 cd->bb = (byte *) malloc( count ) ;
01240
01241 for( ii=0 ; ii < count ; ii++ ){
01242 cd->rr[ii] = xcol[ii].red >> 8 ;
01243 cd->gg[ii] = xcol[ii].green >> 8 ;
01244 cd->bb[ii] = xcol[ii].blue >> 8 ;
01245 }
01246
01247
01248
01249 for( iz=0 ; iz < count ; iz++ )
01250 if( cd->rr[iz] == 255 && cd->gg[iz] == 255 && cd->bb[iz] == 255 ) break ;
01251
01252 cd->nwhite = (iz < count) ? iz : -1 ;
01253
01254
01255
01256 for( iz=0 ; iz < count ; iz++ )
01257 if( cd->rr[iz] == 0 && cd->gg[iz] == 0 && cd->bb[iz] == 0 ) break ;
01258
01259 cd->nblack = (iz < count) ? iz : -1 ;
01260
01261 if( iz < count-1 ){
01262
01263 for( ii=count-1 ; ii > iz ; ii-- )
01264 if( cd->rr[ii] != 0 || cd->gg[ii] != 0 || cd->bb[ii] != 0 ) break ;
01265
01266 count = ii+1 ;
01267
01268 if( count == 1 ){
01269 free(xcol) ; FREE_DC_colordef(cd) ;
01270 fprintf(stderr,"reload_DC_colordef: colormap is all black?\n") ;
01271 EXRETURN ;
01272 }
01273
01274 cd->ncolors = count ;
01275 }
01276
01277 FREE_DC_colordef(dc->cdef) ;
01278
01279 free(xcol) ; dc->cdef = cd ; EXRETURN ;
01280 }
01281
01282
01283
01284 #if defined(__cplusplus) || defined(c_plusplus)
01285 if( vin->c_class == TrueColor ){
01286 #else
01287 if( vin->class == TrueColor ){
01288 #endif
01289
01290 unsigned long r , g , b ;
01291 byte rr, gg, bb ;
01292
01293
01294
01295 cd = (DC_colordef *) malloc( sizeof(DC_colordef) ) ;
01296 cd->classKRH = TrueColor ;
01297 cd->depth = vin->depth ;
01298
01299 cd->rrmask = vin->red_mask ;
01300 cd->ggmask = vin->green_mask ;
01301 cd->bbmask = vin->blue_mask ;
01302 cd->rrshift = 7 - highbit(cd->rrmask) ;
01303 cd->ggshift = 7 - highbit(cd->ggmask) ;
01304 cd->bbshift = 7 - highbit(cd->bbmask) ;
01305
01306
01307
01308 rr = gg = bb = 255 ;
01309
01310 r = (cd->rrshift<0) ? (rr<<(-cd->rrshift))
01311 : (rr>>cd->rrshift) ; r = r & cd->rrmask ;
01312
01313 g = (cd->ggshift<0) ? (gg<<(-cd->ggshift))
01314 : (gg>>cd->ggshift) ; g = g & cd->ggmask ;
01315
01316 b = (cd->bbshift<0) ? (bb<<(-cd->bbshift))
01317 : (bb>>cd->bbshift) ; b = b & cd->bbmask ;
01318
01319 cd->whpix = r | g | b ;
01320
01321 cd->rr = cd->gg = cd->bb = NULL ;
01322
01323 FREE_DC_colordef(dc->cdef) ;
01324
01325 dc->cdef = cd ; EXRETURN ;
01326 }
01327
01328
01329
01330 #if defined(__cplusplus) || defined(c_plusplus)
01331 fprintf(stderr,"reload_DC_colordef: illegal Visual class %s\n",
01332 x11_vcl[vin->c_class] ) ;
01333 #else
01334 fprintf(stderr,"reload_DC_colordef: illegal Visual class %s\n",
01335 x11_vcl[vin->class] ) ;
01336 #endif
01337 EXRETURN ;
01338 }
01339
01340
01341
01342
01343
01344 Pixel DC_rgb_to_pixel( MCW_DC * dc, byte rr, byte gg, byte bb )
01345 {
01346 static MCW_DC * dcold=NULL ;
01347 DC_colordef * cd = dc->cdef ;
01348
01349 if( cd == NULL ){ reload_DC_colordef(dc) ; cd = dc->cdef ; }
01350
01351 switch( cd->classKRH ){
01352
01353
01354
01355 case TrueColor:{
01356 static unsigned long pold=0 ;
01357 static byte rold=0 , gold=0 , bold=0 ;
01358 unsigned long r , g , b ;
01359
01360 if( rr == 0 && gg == 0 && bb == 0 ) return 0 ;
01361 if( rr == 255 && gg == 255 && bb == 255 ) return cd->whpix ;
01362
01363 if( dc == dcold && rr == rold && gg == gold && bb == bold )
01364 return (Pixel) pold ;
01365
01366 rold = rr ; gold = gg ; bold = bb ; dcold = dc ;
01367
01368 r = (cd->rrshift<0) ? (rr<<(-cd->rrshift))
01369 : (rr>>cd->rrshift) ; r = r & cd->rrmask ;
01370
01371 g = (cd->ggshift<0) ? (gg<<(-cd->ggshift))
01372 : (gg>>cd->ggshift) ; g = g & cd->ggmask ;
01373
01374 b = (cd->bbshift<0) ? (bb<<(-cd->bbshift))
01375 : (bb>>cd->bbshift) ; b = b & cd->bbmask ;
01376
01377 pold = r | g | b ;
01378 return (Pixel) pold ;
01379 }
01380
01381
01382
01383
01384
01385 case PseudoColor:{
01386
01387 #define RW 2
01388 #define GW 4
01389 #define BW 1
01390 #define RGBSUM 4
01391
01392 static int iold=0 , rold=0,gold=0,bold=0 ;
01393 int ii , rdif,gdif,bdif,dif , ibest,dbest ;
01394
01395 if( cd->nblack >= 0 && rr == 0 && gg == 0 && bb == 0 )
01396 return (Pixel) cd->nblack ;
01397
01398 if( cd->nwhite >= 0 && rr == 255 && gg == 255 && bb == 255 )
01399 return (Pixel) cd->nwhite ;
01400
01401 if( dc == dcold ){
01402 rdif = rold - rr ;
01403 gdif = gold - gg ;
01404 bdif = bold - bb ; dif = RW*abs(rdif)+GW*abs(gdif)+BW*abs(bdif) ;
01405 if( dif <= RGBSUM ) return (Pixel) iold ;
01406 }
01407
01408 rold = rr ; gold = gg ; bold = bb ; dcold = dc ;
01409
01410 rdif = cd->rr[0] - rr ;
01411 gdif = cd->gg[0] - gg ;
01412 bdif = cd->bb[0] - bb ; dif = RW*abs(rdif)+GW*abs(gdif)+BW*abs(bdif) ;
01413 if( dif <= RGBSUM ){ iold = 0 ; return 0 ; }
01414
01415 ibest = 0 ; dbest = dif ;
01416 for( ii=1 ; ii < cd->ncolors ; ii++ ){
01417 rdif = cd->rr[ii] - rr ;
01418 gdif = cd->gg[ii] - gg ;
01419 bdif = cd->bb[ii] - bb ; dif = RW*abs(rdif)+GW*abs(gdif)+BW*abs(bdif) ;
01420 if( dif <= RGBSUM ){ iold = ii ; return (Pixel) ii ; }
01421 if( dif < dbest ){ ibest = ii ; dbest = dif ; }
01422 }
01423 iold = ibest ; return (Pixel) ibest ;
01424 }
01425 }
01426
01427
01428
01429 return 0 ;
01430 }
01431
01432
01433
01434
01435
01436
01437
01438 Pixel DC_rgb_to_ovpix( MCW_DC * dc, byte rr, byte gg, byte bb )
01439 {
01440 static MCW_DC * dcold=NULL ;
01441 static Pixel pold=0 ;
01442 static int rold=0,gold=0,bold=0 ;
01443 int ii , rdif,gdif,bdif,dif , ibest,dbest ;
01444
01445 if( rr == gg && rr == bb ) return DC_rgb_to_pixel(dc,rr,gg,bb) ;
01446
01447 if( dc == NULL || dc->ovc == NULL || dc->ovc->ncol_ov == 0 ) return 0 ;
01448
01449 if( dc == dcold ){
01450 rdif = rold - rr ;
01451 gdif = gold - gg ;
01452 bdif = bold - bb ;
01453 dif = RW*abs(rdif)+GW*abs(gdif)+BW*abs(bdif) ;
01454 if( dif <= RGBSUM ) return pold ;
01455 }
01456
01457 rold = rr ; gold = gg ; bold = bb ; dcold = dc ;
01458
01459 rdif = DCOV_REDBYTE(dc,0) - rr ;
01460 gdif = DCOV_GREENBYTE(dc,0) - gg ;
01461 bdif = DCOV_BLUEBYTE(dc,0) - bb ;
01462 dif = RW*abs(rdif)+GW*abs(gdif)+BW*abs(bdif) ;
01463 if( dif <= RGBSUM ){ pold = dc->ovc->pix_ov[0] ; return pold ; }
01464
01465 ibest = 0 ; dbest = dif ;
01466 for( ii=1 ; ii < dc->ovc->ncol_ov ; ii++ ){
01467 rdif = DCOV_REDBYTE(dc,ii) - rr ;
01468 gdif = DCOV_GREENBYTE(dc,ii) - gg ;
01469 bdif = DCOV_BLUEBYTE(dc,ii) - bb ;
01470 dif = RW*abs(rdif)+GW*abs(gdif)+BW*abs(bdif) ;
01471 if( dif <= RGBSUM ){ pold = dc->ovc->pix_ov[ii] ; return pold ; }
01472 if( dif < dbest ){ ibest = ii ; dbest = dif ; }
01473 }
01474 pold = dc->ovc->pix_ov[ibest] ; return pold ;
01475 }
01476
01477
01478
01479
01480
01481 void DC_rgb_to_ovrgb( MCW_DC * dc , int nlist , int * list , int shade ,
01482 byte *rrin , byte *ggin, byte *bbin )
01483 {
01484 int jj,jtop,ii , rdif,gdif,bdif,dif , ibest,dbest ;
01485 byte rr=*rrin , gg=*ggin , bb=*bbin , mm , rt,gt,bt , rtbest,gtbest,btbest;
01486 float brig , fac ;
01487
01488 if( rr == gg && rr == bb ) return ;
01489
01490 if( dc == NULL || dc->ovc == NULL || dc->ovc->ncol_ov == 0 ) return ;
01491
01492
01493
01494 brig = BRIGHTNESS(rr,gg,bb) ; mm = (byte)(brig + 0.499) ;
01495 dbest = RW*abs(mm-rr)+GW*abs(mm-gg)+BW*abs(mm-bb) ;
01496 if( dbest <= RGBSUM ){
01497 *rrin = *ggin = *bbin = mm ; return ;
01498 }
01499 ibest = 0 ; rtbest = gtbest = btbest = mm ;
01500
01501
01502
01503 jtop = (nlist > 0) ? nlist : dc->ovc->ncol_ov ;
01504 for( jj=0 ; jj < jtop ; jj++ ){
01505 ii = (nlist > 0) ? list[jj] : jj ;
01506 if( ii <= 0 || ii >= dc->ovc->ncol_ov || dc->ovc->bright_ov[ii] <= 0.0 ) continue ;
01507
01508 rt = DCOV_REDBYTE(dc,ii) ; gt = DCOV_GREENBYTE(dc,ii) ; bt = DCOV_BLUEBYTE(dc,ii) ;
01509 if( shade ){
01510 fac = brig / dc->ovc->bright_ov[ii] ;
01511 rt = (byte)( fac*rt + 0.499 ) ;
01512 gt = (byte)( fac*gt + 0.499 ) ;
01513 bt = (byte)( fac*bt + 0.499 ) ;
01514 }
01515 dif = RW*abs(rt-rr)+GW*abs(gt-gg)+BW*abs(bt-bb) ;
01516 if( dif <= RGBSUM ){
01517 *rrin = rt ; *ggin = gt ; *bbin = bt ; return ;
01518 }
01519 if( dif < dbest ){
01520 ibest = ii ; dbest = dif ; rtbest = rt ; gtbest = gt ; btbest = bt ;
01521 }
01522 }
01523
01524 *rrin = rtbest ; *ggin = gtbest ; *bbin = btbest ; return ;
01525 }
01526
01527
01528
01529
01530
01531 void DC_pixel_to_rgb( MCW_DC * dc , Pixel ppp ,
01532 byte * rr , byte * gg , byte * bb )
01533 {
01534 DC_colordef * cd = dc->cdef ;
01535
01536 if( cd == NULL ){ reload_DC_colordef(dc) ; cd = dc->cdef ; }
01537
01538 switch( cd->classKRH ){
01539
01540
01541
01542 case TrueColor:{
01543 unsigned long r , g , b ;
01544
01545 if( ppp == 0 ){ *rr = *bb = *gg = 0 ; return ; }
01546 if( ppp == cd->whpix ){ *rr = *bb = *gg = 255 ; return ; }
01547
01548 r = ppp & cd->rrmask ;
01549 *rr = (cd->rrshift<0) ? (r>>(-cd->rrshift)) : (r<<cd->rrshift) ;
01550
01551 g = ppp & cd->ggmask ;
01552 *gg = (cd->ggshift<0) ? (g>>(-cd->ggshift)) : (g<<cd->ggshift) ;
01553
01554 b = ppp & cd->bbmask ;
01555 *bb = (cd->bbshift<0) ? (b>>(-cd->bbshift)) : (b<<cd->bbshift) ;
01556
01557 return ;
01558 }
01559
01560
01561
01562 case PseudoColor:{
01563 int ii = (int) ppp ;
01564 *rr = cd->rr[ii] ; *gg = cd->gg[ii] ; *bb = cd->bb[ii] ; return ;
01565 }
01566 }
01567
01568 return ;
01569 }
01570
01571
01572
01573
01574
01575
01576
01577
01578 int DC_parse_color( MCW_DC *dc, char *str, float *rr, float *gg, float *bb )
01579 {
01580 XColor cell ; int ok ;
01581
01582 if( str == NULL || *str == '\0' ) return 1 ;
01583
01584 if( strncmp(str,"AJJ:",4) == 0 ){
01585 float ang=-6666.0 ;
01586 sscanf(str+4,"%f",&ang) ;
01587 if( ang != -6666.0 ){
01588 rgbyte col = DC_spectrum_AJJ( ang , 0.8 ) ;
01589 *rr = col.r / 255.0 ;
01590 *gg = col.g / 255.0 ;
01591 *bb = col.b / 255.0 ;
01592 return 0 ;
01593 }
01594 return 1 ;
01595 }
01596
01597 ok = XParseColor( dc->display , dc->colormap , str, &cell ) ;
01598 if( ok ){
01599 *rr = cell.red / 65535.0 ;
01600 *gg = cell.green / 65535.0 ;
01601 *bb = cell.blue / 65535.0 ;
01602 return 0 ;
01603 }
01604 return 1 ;
01605 }