summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJun FURUSE / 古瀬 淳 <jun.furuse@gmail.com>1999-02-19 17:08:27 +0000
committerJun FURUSE / 古瀬 淳 <jun.furuse@gmail.com>1999-02-19 17:08:27 +0000
commit6feb22a648fa728af17c94c28402441cdd07583f (patch)
tree67999a933ab31f1f43a910b2474967cced99970e
parent0ecbd9a5ab67f4a81314b42a91da4ebcbc50f285 (diff)
For true color map images, the color query is impressively optimized.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@2296 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r--otherlibs/graph/color.c31
-rw-r--r--otherlibs/graph/libgraph.h5
-rw-r--r--otherlibs/graph/make_img.c16
3 files changed, 45 insertions, 7 deletions
diff --git a/otherlibs/graph/color.c b/otherlibs/graph/color.c
index 75addc608..c2f569738 100644
--- a/otherlibs/graph/color.c
+++ b/otherlibs/graph/color.c
@@ -29,6 +29,11 @@ static struct color_cache_entry color_cache[Color_cache_size];
static int num_overflows = 0;
+Bool direct_rgb = False;
+int byte_order;
+int bitmap_unit;
+int bits_per_pixel;
+
void gr_init_color_cache(void)
{
int i;
@@ -46,10 +51,22 @@ unsigned long gr_pixel_rgb(int rgb)
unsigned int r, g, b;
int h, i;
XColor color;
+ unsigned short tmp;
r = (rgb >> 16) & 0xFF;
g = (rgb >> 8) & 0xFF;
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);
+ }
+ }
+
h = Hash_rgb(r, g, b);
i = h;
while(1) {
@@ -57,13 +74,13 @@ unsigned long gr_pixel_rgb(int rgb)
if (color_cache[i].rgb == rgb) return color_cache[i].pixel;
i = (i + 1) & (Color_cache_size - 1);
if (i == h) {
- /* Cache is full. Instead of inserting at slot h, which causes
- thrasing if many colors hash to the same value,
- insert at h + n where n is pseudo-random and
- smaller than Color_cache_slack */
- int slack = num_overflows++ & (Color_cache_slack - 1);
- i = (i + slack) & (Color_cache_size - 1);
- break;
+ /* Cache is full. Instead of inserting at slot h, which causes
+ thrasing if many colors hash to the same value,
+ insert at h + n where n is pseudo-random and
+ smaller than Color_cache_slack */
+ int slack = num_overflows++ & (Color_cache_slack - 1);
+ i = (i + slack) & (Color_cache_size - 1);
+ break;
}
}
color.red = r * 0x101;
diff --git a/otherlibs/graph/libgraph.h b/otherlibs/graph/libgraph.h
index 0e58bace2..ac8a50bd5 100644
--- a/otherlibs/graph/libgraph.h
+++ b/otherlibs/graph/libgraph.h
@@ -32,6 +32,11 @@ extern int grx, gry; /* Coordinates of the current point */
extern unsigned long grcolor; /* Current drawing color */
extern XFontStruct * grfont; /* Current font */
+extern Bool direct_rgb;
+extern int byte_order;
+extern int bitmap_unit;
+extern int bits_per_pixel;
+
#define Wcvt(y) (grwindow.h - 1 - (y))
#define Bcvt(y) (grbstore.h - 1 - (y))
#define WtoB(y) ((y) + grbstore.h - grwindow.h)
diff --git a/otherlibs/graph/make_img.c b/otherlibs/graph/make_img.c
index 2d6bfe960..fdd601cba 100644
--- a/otherlibs/graph/make_img.c
+++ b/otherlibs/graph/make_img.c
@@ -40,6 +40,22 @@ value gr_make_image(value m)
XDefaultDepth(grdisplay, grscreen),
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;