summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--otherlibs/graph/color.c120
-rw-r--r--otherlibs/graph/make_img.c15
-rw-r--r--otherlibs/graph/open.c2
3 files changed, 112 insertions, 25 deletions
diff --git a/otherlibs/graph/color.c b/otherlibs/graph/color.c
index 2c1a58578..024bd71dd 100644
--- a/otherlibs/graph/color.c
+++ b/otherlibs/graph/color.c
@@ -13,6 +13,7 @@
/* $Id$ */
#include "libgraph.h"
+#include <X11/Xatom.h>
/* Cache to speed up the translation rgb -> pixel value. */
@@ -30,10 +31,106 @@ static struct color_cache_entry color_cache[Color_cache_size];
static int num_overflows = 0;
+/* rgb -> pixel conversion *without* display connection */
+
Bool direct_rgb = False;
-int byte_order;
-int bitmap_unit;
-int bits_per_pixel;
+int red_l, red_r;
+int green_l, green_r;
+int blue_l, blue_r;
+unsigned long red_mask, green_mask, blue_mask;
+
+/* rgb -> pixel table */
+unsigned long red_vals[256];
+unsigned long green_vals[256];
+unsigned long blue_vals[256];
+
+void get_shifts( unsigned long mask, int *lsl, int *lsr )
+{
+ int l = 0;
+ int r = 0;
+ int bit = 1;
+ if ( mask == 0 ){ *lsl = -1; *lsr = -1; return; }
+
+ for( l = 0; l < 32; l++ ){
+ if( bit & mask ){ break; }
+ bit = bit << 1;
+ }
+ for( r = l; r < 32; r++ ){
+ if( ! (bit & mask) ){ break; }
+ bit = bit << 1;
+ }
+ /* fix r */
+ if ( r == 32 ) { r = 31; }
+ *lsl = l;
+ *lsr = 16 - (r - l);
+}
+
+void gr_init_direct_rgb_to_pixel(void)
+{
+ Visual *visual;
+ int i;
+
+ visual = DefaultVisual(grdisplay,grscreen);
+
+ if ( visual->class == TrueColor || visual->class == DirectColor ){
+ int lsl, lsr;
+
+ red_mask = visual->red_mask;
+ green_mask = visual->green_mask;
+ blue_mask = visual->blue_mask;
+
+#ifdef QUICKCOLORDEBUG
+ fprintf(stderr, "visual %lx %lx %lx\n",
+ red_mask,
+ green_mask,
+ blue_mask);
+#endif
+
+ get_shifts(red_mask, &red_l, &red_r);
+#ifdef QUICKCOLORDEBUG
+ fprintf(stderr, "red %d %d\n", red_l, red_r);
+#endif
+ for(i=0; i<256; i++){
+ red_vals[i] = (((i << 8) + i) >> red_r) << red_l;
+ }
+
+ get_shifts(green_mask, &green_l, &green_r);
+#ifdef QUICKCOLORDEBUG
+ fprintf(stderr, "green %d %d\n", green_l, green_r);
+#endif
+ for(i=0; i<256; i++){
+ green_vals[i] = (((i << 8) + i) >> green_r) << green_l;
+ }
+
+ get_shifts(blue_mask, &blue_l, &blue_r);
+#ifdef QUICKCOLORDEBUG
+ fprintf(stderr, "blue %d %d\n", blue_l, blue_r);
+#endif
+ for(i=0; i<256; i++){
+ blue_vals[i] = (((i << 8) + i) >> blue_r) << blue_l;
+ }
+
+ if( red_l < 0 || red_r < 0 ||
+ green_l < 0 || green_r < 0 ||
+ blue_l < 0 || blue_r < 0 ){
+#ifdef QUICKCOLORDEBUG
+ fprintf(stderr, "Damn, boost failed\n");
+#endif
+ direct_rgb = False;
+ } else {
+#ifdef QUICKCOLORDEBUG
+ fprintf(stderr, "Boost ok\n");
+#endif
+ direct_rgb = True;
+ }
+ } else {
+ /* we cannot use direct_rgb_to_pixel */
+#ifdef QUICKCOLORDEBUG
+ fprintf(stderr, "No boost!\n");
+#endif
+ direct_rgb = False;
+ }
+}
void gr_init_color_cache(void)
{
@@ -59,13 +156,7 @@ unsigned long gr_pixel_rgb(int rgb)
b = rgb & 0xFF;
if (direct_rgb){
- switch ( bits_per_pixel ){
- case 16:
- tmp = ((r >> 3) << 11) + ((g >> 2) << 5) + ((b >> 3) << 0);
- return (unsigned long) tmp;
- case 32:
- return (r << 16) + (g << 8) + (b << 0);
- }
+ return red_vals[r] | green_vals[g] | blue_vals[b];
}
h = Hash_rgb(r, g, b);
@@ -95,9 +186,18 @@ unsigned long gr_pixel_rgb(int rgb)
int gr_rgb_pixel(long unsigned int pixel)
{
+ register int r,g,b;
+
XColor color;
int i;
+ if (direct_rgb) {
+ r = (((pixel & red_mask) >> red_l) << 8) >> (16 - red_r);
+ g = (((pixel & green_mask) >> green_l) << 8) >> (16 - green_r);
+ b = (((pixel & blue_mask) >> blue_l) << 8) >> (16 - blue_r);
+ return (r << 16) + (g << 8) + b;
+ }
+
if (pixel == grblack) return 0;
if (pixel == grwhite) return 0xFFFFFF;
diff --git a/otherlibs/graph/make_img.c b/otherlibs/graph/make_img.c
index ae655685b..a96997bc9 100644
--- a/otherlibs/graph/make_img.c
+++ b/otherlibs/graph/make_img.c
@@ -42,21 +42,6 @@ value gr_make_image(value m)
ZPixmap, 0, NULL, width, height,
BitmapPad(grdisplay), 0);
- /* To optimize RGB => color id calculation */
- if( !direct_rgb ){
- /* they are declared in color.c */
- byte_order = idata->byte_order;
- bitmap_unit = idata->bitmap_unit;
- bits_per_pixel = idata->bits_per_pixel;
-#ifdef DIRECT_RGB_DEBUG
- fprintf(stderr, "Byte_order: %d = %s\n", byte_order,
- byte_order ? "LSBFirst" : "MSBFirst");
- fprintf(stderr, "Bitmp_unit: %d\n", bitmap_unit);
- fprintf(stderr, "Bits per pixel: %d\n", idata->bits_per_pixel);
-#endif
- direct_rgb = True;
- }
-
bdata = (char *) stat_alloc(height * idata->bytes_per_line);
idata->data = bdata;
has_transp = False;
diff --git a/otherlibs/graph/open.c b/otherlibs/graph/open.c
index a81d982ac..db2782ab5 100644
--- a/otherlibs/graph/open.c
+++ b/otherlibs/graph/open.c
@@ -192,6 +192,7 @@ value gr_open_graph(value arg)
gry = 0;
/* Reset the color cache */
gr_init_color_cache();
+ gr_init_direct_rgb_to_pixel();
return Val_unit;
}
@@ -257,6 +258,7 @@ value gr_clear_graph(void)
XFlush(grdisplay);
}
gr_init_color_cache();
+ gr_init_direct_rgb_to_pixel();
return Val_unit;
}