diff --git a/src/modules/image/image.h b/src/modules/image/image.h
index 64450704b0cc3a79e23354d90648bae4e9ac51db..8540e77cead4807e857bff4dfa729b8c18a476d4 100644
--- a/src/modules/image/image.h
+++ b/src/modules/image/image.h
@@ -4,6 +4,7 @@
 #define QUANT_MAP_SKIP_BITS (8-(QUANT_MAP_BITS))
 #define QUANT_MAP_THIS(X) ((X)>>QUANT_MAP_SKIP_BITS)
 #define QUANT_MAP_REAL (1L<<QUANT_MAP_BITS)
+#define QUANT_SELECT_CACHE 5
 
 #define COLOURTYPE unsigned char
 
@@ -41,6 +42,11 @@ struct colortable
       unsigned char used; 
       struct map_entry *next;
    } map[QUANT_MAP_REAL][QUANT_MAP_REAL][QUANT_MAP_REAL];
+   struct rgb_cache
+   {
+      rgb_group index;
+      int value;
+   } cache[QUANT_SELECT_CACHE];
    rgb_group clut[1];
 };
 
diff --git a/src/modules/image/quant.c b/src/modules/image/quant.c
index e241a340308d685bfb0a3f144433a763c352d816..d08ba636a7139b59c5652ff32fd468e85214d0d9 100644
--- a/src/modules/image/quant.c
+++ b/src/modules/image/quant.c
@@ -564,6 +564,14 @@ struct colortable *colortable_from_array(struct array *arr,char *from)
   CHRONO("done");
 
   free(tbl);
+
+  for (i=0; i<QUANT_SELECT_CACHE; i++)
+     ct->cache[i].index=white;
+  j=colortable_rgb(ct,black); /* ^^ dont find it in the cache... */
+  for (i=0; i<QUANT_SELECT_CACHE; i++)
+     ct->cache[i].index=black,
+     ct->cache[i].value=j;
+
   CHRONO("really done");
   return ct;
 }
@@ -575,11 +583,18 @@ struct colortable *colortable_from_array(struct array *arr,char *from)
 
 int colortable_rgb(struct colortable *ct,rgb_group rgb)
 {
-   struct map_entry *me,**eme;
-   int mindistance,best=0;
-   me=&(ct->map[QUANT_MAP_THIS(rgb.r)]
-	       [QUANT_MAP_THIS(rgb.g)]
-               [QUANT_MAP_THIS(rgb.b)]);
+   struct map_entry *me,**eme,**beme,*feme;
+   int mindistance,best=0,i;
+
+   if (ct->cache->index.r==rgb.r &&
+       ct->cache->index.g==rgb.g &&
+       ct->cache->index.b==rgb.b) 
+      return ct->cache->value;
+
+   feme=me=&(ct->map[QUANT_MAP_THIS(rgb.r)]
+	            [QUANT_MAP_THIS(rgb.g)]
+ 	            [QUANT_MAP_THIS(rgb.b)]);
+
 #ifdef QUANT_DEBUG_RGB
    fprintf(stderr,"%d,%d,%d -> %lu %lu %lu: ",rgb.r,rgb.g,rgb.b,
    QUANT_MAP_THIS(rgb.r),
@@ -596,9 +611,28 @@ int colortable_rgb(struct colortable *ct,rgb_group rgb)
 #endif
       return me->cl; 
    }
+   for (i=1; i<QUANT_SELECT_CACHE; i++)
+      if (ct->cache[i].index.r==rgb.r &&
+	  ct->cache[i].index.g==rgb.g &&
+	  ct->cache[i].index.b==rgb.b) 
+      {
+	 best=ct->cache[i].value;
+
+	 MEMMOVE(ct->cache+1,ct->cache,
+		 i*sizeof(struct rgb_cache));
+	 ct->cache[0].index=rgb;
+	 ct->cache[0].value=best;
+
+#ifdef QUANT_DEBUG_RGB
+fprintf(stderr,"cache: %lu: %d,%d,%d\n",best,ct->clut[best].r,ct->clut[best].g,ct->clut[best].b);
+#endif
+	 return best;
+      }
+
    mindistance=DISTANCE(rgb,ct->clut[me->cl]);
    best=me->cl;
-   while ( (me=me->next) && mindistance)
+   me=me->next; eme=&(me->next); beme=NULL;
+   while ( me && mindistance )
    {
       int d;
 #ifdef QUANT_DEBUG_RGB
@@ -609,7 +643,27 @@ fprintf(stderr,"%lx %d,%d,%d ",me,ct->clut[me->cl].r,ct->clut[me->cl].g,ct->clut
       {
 	 mindistance=DISTANCE(rgb,ct->clut[me->cl]);
 	 best=me->cl;
+	 beme=eme;
       }
+      eme=&(me->next);
+      me=me->next;
+   }
+   if (!mindistance && beme) /* exact match, place first */
+   {
+      struct map_entry e;
+      e=*feme;
+      me=*beme;
+      *feme=*me;
+      *beme=me->next;
+      *me=e;
+      feme->next=me;
+   }
+   else /* place in cache */
+   {
+      MEMMOVE(ct->cache+1,ct->cache,
+	      (QUANT_SELECT_CACHE-1)*sizeof(struct rgb_cache));
+      ct->cache[0].index=rgb;
+      ct->cache[0].value=best;
    }
 #ifdef QUANT_DEBUG_RGB
 fprintf(stderr,"%lx ",me);