2 #include <Xw_Extension.h>
4 /* ifdef then trace on */
6 #define TRACE_ALLOC_COLOR
10 XW_STATUS Xw_alloc_color(pcolormap,r,g,b,pixel,isapproximate):
11 XW_EXT_COLORMAP *pcolormap
12 float r,g,b ; Red,Green,Blue color value 0. >= x <= 1.
13 unsigned long pixel ;Returned Color pixel value
16 Get the color pixel value from an {r,g,b} color definition.
17 Returned the existing color pixel or create an other if it don't exist.
19 Returns ERROR if Bad Color pixel
20 Returns SUCCESS if Successful
24 #define OCC38 /* SAV 30/11/01 correcred: gamma correction formula */
26 static double theGammaCorrection = 1.0;
27 static Colormap theColormap;
28 static XColor theColors[MAXCOLOR];
29 static unsigned char theFilters[MAXCOLOR];
32 XW_STATUS Xw_alloc_color (XW_EXT_COLORMAP* pcolormap,
33 float r,float g,float b,unsigned long *pixel,int *isapproximate)
35 XW_STATUS Xw_alloc_color (pcolormap,r,g,b,pixel,isapproximate)
36 XW_EXT_COLORMAP *pcolormap;
40 #endif /*XW_PROTOTYPE*/
47 unsigned char filter='\0';
50 if( !Xw_isdefine_colormap(pcolormap) ) {
51 /*ERROR*Bad EXT_COLORMAP Address*/
52 Xw_set_error(42,"Xw_alloc_color",pcolormap) ;
56 *isapproximate = False;
57 if( _CCLASS == TrueColor ) {
58 if( theColormap != _CINFO.colormap ) {
59 theColormap = _CINFO.colormap;
60 if( Xw_get_env("Xw_SET_GAMMA_CORRECTION",svalue,sizeof(svalue)) ) {
61 if( strlen(svalue) > 0 ) {
63 sscanf(svalue,"%f",&gamma);
66 theGammaCorrection = 1. / gamma;
68 if( gamma > 0. ) theGammaCorrection = gamma;
71 printf(" Xw_SET_GAMMA_CORRECTION is %f\n",theGammaCorrection) ;
75 if( theGammaCorrection != 1.0 ) {
76 color.red = (unsigned short) (pow((double)r,theGammaCorrection)*65535.);
77 color.green = (unsigned short) (pow((double)g,theGammaCorrection)*65535.);
78 color.blue = (unsigned short) (pow((double)b,theGammaCorrection)*65535.);
80 color.red = (unsigned short) (r*65535.);
81 color.green = (unsigned short) (g*65535.);
82 color.blue = (unsigned short) (b*65535.);
84 status = XAllocColor(_CDISPLAY,_CINFO.colormap,&color) ;
86 unsigned long mask = _CVISUAL->map_entries-1 ;
87 unsigned long red = (unsigned long) (r * mask) ;
88 unsigned long green = (unsigned long) (g * mask) ;
89 unsigned long blue = (unsigned long) (b * mask) ;
91 mask = _CVISUAL->red_mask;
92 while ( !(mask & 0x01) ) { mask >>= 1; red <<= 1; }
93 mask = _CVISUAL->green_mask;
94 while ( !(mask & 0x01) ) { mask >>= 1; green <<= 1; }
95 mask = _CVISUAL->blue_mask;
96 while ( !(mask & 0x01) ) { mask >>= 1; blue <<= 1; }
97 color.pixel = red|green|blue ;
101 color.red = (unsigned short) (r*65535.);
102 color.green = (unsigned short) (g*65535.);
103 color.blue = (unsigned short) (b*65535.);
104 status = XAllocColor(_CDISPLAY,_CINFO.colormap,&color) ;
106 int i,j,ncolor = min(MAXCOLOR,_CVISUAL->map_entries);
109 if( theColormap != _CINFO.colormap ) {
110 theColormap = _CINFO.colormap;
111 for( i=0 ; i<ncolor ; i++ ) {
112 theColors[i].pixel = i;
115 XQueryColors(_CDISPLAY,_CINFO.colormap,theColors,ncolor);
116 for( i=0 ; i<ncolor ; i++ ) {
118 if( theColors[i].red > theColors[i].blue ) filter |= 1;
119 else if( theColors[i].blue > theColors[i].red ) filter |= 4;
120 if( theColors[i].red > theColors[i].green ) filter |= 2;
121 else if( theColors[i].green > theColors[i].red ) filter |= 4;
122 if( theColors[i].blue > theColors[i].green ) filter |= 2;
123 else if( theColors[i].green > theColors[i].blue ) filter |= 1;
124 theFilters[i] = filter;
129 if( color.red > color.blue ) filter |= 1;
130 else if( color.blue > color.red ) filter |= 4;
131 if( color.red > color.green ) filter |= 2;
132 else if( color.green > color.red ) filter |= 4;
133 if( color.blue > color.green ) filter |= 2;
134 else if( color.green > color.blue ) filter |= 1;
136 for( i=j=0 ; i<ncolor ; i++ ) {
137 if( filter == theFilters[i] ) {
138 if( filter ) { /* This is a color */
139 dr = abs( color.red - theColors[i].red ) >> 8;
140 dg = abs( color.green - theColors[i].green ) >> 8;
141 db = abs( color.blue - theColors[i].blue ) >> 8;
142 if( (dr <= drmin) && (dg <= dgmin) && (db <= dbmin) ) {
143 j = i; drmin = dr; dgmin = dg; dbmin = db;
145 } else { /* This is a gray */
146 dr = abs( color.red - theColors[i].red ) >> 8;
155 if( (drmin > 0) || (dgmin > 0) || (dbmin > 0) ) *isapproximate = True;
157 if( drmin > 0 ) *isapproximate = True;
160 color.pixel = theColors[j].pixel;
163 *pixel = color.pixel;
166 #ifdef TRACE_ALLOC_COLOR
167 if( Xw_get_trace() ) {
168 printf(" %d = Xw_alloc_color(%lx,%f,%f,%f,%ld,%d)\n",
169 status,(long ) pcolormap,r,g,b,*pixel,*isapproximate) ;
170 if( *isapproximate ) {
172 printf(" Is an approximate color of delta-GRAY (%f)\n",(float)drmin/65535.);
174 printf(" Is an approximate color of delta-COLOR (%f,%f,%f)\n",
177 (float)dbmin/65535.);
182 return (XW_STATUS)status;