0022627: Change OCCT memory management defaults
[occt.git] / src / Xw / Xw_alloc_color.cxx
1
2 #include <Xw_Extension.h>
3
4         /* ifdef then trace on */
5 #ifdef TRACE
6 #define TRACE_ALLOC_COLOR
7 #endif
8
9 /*
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
14    bool isapproximate
15
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.
18
19         Returns ERROR if Bad Color pixel
20         Returns SUCCESS if Successful      
21
22 */
23
24 #define OCC38      /* SAV 30/11/01 correcred: gamma correction formula */
25
26 static double theGammaCorrection = 1.0;
27 static Colormap theColormap;
28 static XColor theColors[MAXCOLOR];
29 static unsigned char theFilters[MAXCOLOR];
30
31 #ifdef XW_PROTOTYPE
32 XW_STATUS Xw_alloc_color (XW_EXT_COLORMAP* pcolormap,
33                         float r,float g,float b,unsigned long *pixel,int *isapproximate)
34 #else
35 XW_STATUS Xw_alloc_color (pcolormap,r,g,b,pixel,isapproximate)
36 XW_EXT_COLORMAP *pcolormap;
37 float r,g,b ;
38 unsigned long *pixel;
39 int *isapproximate;
40 #endif /*XW_PROTOTYPE*/
41 {
42 int status = False;
43 int drmin = 65536;
44 int dgmin = 65536;
45 int dbmin = 65536;
46 XColor color;
47 unsigned char filter='\0';
48 char svalue[6];
49
50         if( !Xw_isdefine_colormap(pcolormap) ) {
51           /*ERROR*Bad EXT_COLORMAP Address*/
52           Xw_set_error(42,"Xw_alloc_color",pcolormap) ;
53           return (XW_ERROR) ;
54         }
55
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 ) {
62                 float gamma; 
63                 sscanf(svalue,"%f",&gamma);
64 #ifdef OCC38
65                 if( gamma >  0. )
66                   theGammaCorrection = 1. / gamma;
67 #else
68                 if( gamma >  0. ) theGammaCorrection = gamma;
69 #endif
70               }
71               printf(" Xw_SET_GAMMA_CORRECTION is %f\n",theGammaCorrection) ;
72             }
73           }
74           color.pixel = 0;
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.);
79           } else {
80             color.red = (unsigned short) (r*65535.);
81             color.green = (unsigned short) (g*65535.);
82             color.blue = (unsigned short) (b*65535.);
83           }
84           status = XAllocColor(_CDISPLAY,_CINFO.colormap,&color) ;
85           if( !status ) {
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) ;
90
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 ;
98           }
99         } else { 
100           color.pixel = 0;
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) ;
105           if( !status ) {
106             int i,j,ncolor = min(MAXCOLOR,_CVISUAL->map_entries);
107             int dr,dg,db;
108
109             if( theColormap != _CINFO.colormap ) {
110               theColormap = _CINFO.colormap;
111               for( i=0 ; i<ncolor ; i++ ) {
112                 theColors[i].pixel = i;
113                 theFilters[i] = 0;
114               }
115               XQueryColors(_CDISPLAY,_CINFO.colormap,theColors,ncolor);
116               for( i=0 ; i<ncolor ; i++ ) {
117                 filter = 0;
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;
125               }
126             }
127
128             filter = 0;
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;
135
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;
144                   }  
145                 } else {                        /* This is a gray */
146                   dr = abs( color.red - theColors[i].red ) >> 8;
147                   if( dr <= drmin ) {
148                     j = i; drmin = dr;
149                   }  
150                 }
151               }
152             }
153
154             if( filter ) {
155               if( (drmin > 0) || (dgmin > 0) || (dbmin > 0) ) *isapproximate = True;
156             } else {
157               if( drmin > 0 ) *isapproximate = True;
158             }
159
160             color.pixel = theColors[j].pixel;
161           }
162         }
163         *pixel = color.pixel;
164         status = XW_SUCCESS;
165
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 ) {
171       if( !filter ) {
172         printf("      Is an approximate color of delta-GRAY (%f)\n",(float)drmin/65535.);
173       } else {
174         printf("      Is an approximate color of delta-COLOR (%f,%f,%f)\n",
175                                                         (float)drmin/65535.,
176                                                         (float)dgmin/65535.,
177                                                         (float)dbmin/65535.);
178       }
179     }
180 }
181 #endif
182     return (XW_STATUS)status;
183 }