diff --git a/src/modules/image/image.c b/src/modules/image/image.c index 49e975eafb9121c40b29dda8d6b05b9fe8a5fba0..ee608296658ded1514ed41a6990d2f243ff4095c 100644 --- a/src/modules/image/image.c +++ b/src/modules/image/image.c @@ -1,4 +1,4 @@ -/* $Id: image.c,v 1.32 1996/12/05 22:53:25 law Exp $ */ +/* $Id: image.c,v 1.33 1996/12/05 23:50:51 law Exp $ */ #include "global.h" @@ -7,7 +7,7 @@ #include "stralloc.h" #include "global.h" -RCSID("$Id: image.c,v 1.32 1996/12/05 22:53:25 law Exp $"); +RCSID("$Id: image.c,v 1.33 1996/12/05 23:50:51 law Exp $"); #include "types.h" #include "macros.h" #include "object.h" @@ -1411,6 +1411,38 @@ static void image_map_closest(INT32 args) ct=colortable_from_array(sp[-args].u.array,"image->map_closest()\n"); pop_n_elems(args); + i=THIS->xsize*THIS->ysize; + s=THIS->img; + d=((struct image*)(o->storage))->img; + while (i--) + { + *d=ct->clut[colortable_rgb_nearest(ct,*s)]; + d++; *s++; + } + + colortable_free(ct); + push_object(o); +} + +static void image_map_fast(INT32 args) +{ + struct colortable *ct; + long i; + rgb_group *d,*s; + struct object *o; + + if (!THIS->img) error("no image\n"); + if (args<1 + || sp[-args].type!=T_ARRAY) + error("illegal argument to image->map_closest()\n"); + + push_int(THIS->xsize); + push_int(THIS->ysize); + o=clone(image_program,2); + + ct=colortable_from_array(sp[-args].u.array,"image->map_closest()\n"); + pop_n_elems(args); + i=THIS->xsize*THIS->ysize; s=THIS->img; d=((struct image*)(o->storage))->img; @@ -1631,6 +1663,8 @@ void init_image_programs() add_function("map_closest",image_map_closest, "function(:object)",0); + add_function("map_fast",image_map_fast, + "function(:object)",0); add_function("map_fs",image_map_fs, "function(:object)",0); add_function("select_colors",image_select_colors, diff --git a/src/modules/image/image.h b/src/modules/image/image.h index 3a1b0382432037fcc0da72830d1520a2350ceba7..c37001dc2847f855ccd298b38f44020b748360b0 100644 --- a/src/modules/image/image.h +++ b/src/modules/image/image.h @@ -1,4 +1,4 @@ -/* $Id: image.h,v 1.15 1996/12/05 22:53:26 law Exp $ */ +/* $Id: image.h,v 1.16 1996/12/05 23:50:52 law Exp $ */ #define MAX_NUMCOL 32768 @@ -61,6 +61,7 @@ struct colortable struct colortable *colortable_quant(struct image *img,int numcol); int colortable_rgb(struct colortable *ct,rgb_group rgb); +int colortable_rgb_nearest(struct colortable *ct,rgb_group rgb); void colortable_free(struct colortable *ct); struct colortable *colortable_from_array(struct array *arr,char *from); diff --git a/src/modules/image/matrix.c b/src/modules/image/matrix.c index 3c442ac7c3c6efe7aca7e17ced1e761232e04a29..54c90ac0bd08426adf9af0d2ead42e47af89dae5 100644 --- a/src/modules/image/matrix.c +++ b/src/modules/image/matrix.c @@ -1,4 +1,4 @@ -/* $Id: matrix.c,v 1.7 1996/12/03 22:40:46 law Exp $ */ +/* $Id: matrix.c,v 1.8 1996/12/05 23:50:53 law Exp $ */ #include "global.h" @@ -133,7 +133,10 @@ static INLINE void scale_add_line(rgbd_group *new,INT32 yn,INT32 newx, scale_add_pixel(new,(INT32)xn,img,x,xndxd); if (dx>=1.0 && (xd=(INT32)(xn+dx)-(INT32)(xn))>1) while (--xd) + { + new++; scale_add_pixel(new,(INT32)(xn+xd),img,x,py); + } xndxd=py*decimals(xn+dx); new++; if (xndxd) diff --git a/src/modules/image/quant.c b/src/modules/image/quant.c index 751a6204fef07184f93941a480c8feb7a92f8af0..b50c912964bac35bd407b62d0cffcdaf7cfae40d 100644 --- a/src/modules/image/quant.c +++ b/src/modules/image/quant.c @@ -1,4 +1,4 @@ -/* $Id: quant.c,v 1.16 1996/12/05 22:53:27 law Exp $ */ +/* $Id: quant.c,v 1.17 1996/12/05 23:50:54 law Exp $ */ /* @@ -660,7 +660,7 @@ struct colortable *colortable_from_array(struct array *arr,char *from) int colortable_rgb(struct colortable *ct,rgb_group rgb) { - int i,best,di; + int i,best; if (ct->cache->index.r==rgb.r && ct->cache->index.g==rgb.g && @@ -745,15 +745,67 @@ fprintf(stderr,"cache: %lu: %d,%d,%d\n",best,ct->clut[best].r,ct->clut[best].g,c #endif -#if 0 + /* place in cache */ +#if QUANT_SELECT_CACHE>1 + MEMMOVE(ct->cache+1,ct->cache, + (QUANT_SELECT_CACHE-1)*sizeof(struct rgb_cache)); +#endif + ct->cache[0].index=rgb; + ct->cache[0].value=best; + +#ifdef QUANT_DEBUG_RGB +fprintf(stderr," -> %lu: %d,%d,%d\n",best, + ct->clut[best].r,ct->clut[best].g,ct->clut[best].b); +#endif + return best; +} + +int colortable_rgb_nearest(struct colortable *ct,rgb_group rgb) +{ + int i,best=0,di,di2; + rgb_group *prgb; + + if (ct->cache->index.r==rgb.r && + ct->cache->index.g==rgb.g && + ct->cache->index.b==rgb.b) + return ct->cache->value; + +#ifdef QUANT_DEBUG_RGB +fprintf(stderr,"rgb: %d,%d,%d\n",rgb.r,rgb.g,rgb.b); +#endif + +#if QUANT_SELECT_CACHE>1 + 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; + } +#endif + + /* find node */ + di=1000000L; for (i=0; i<ct->numcol; i++) - if (DISTANCE(ct->clut[i],rgb)<di) + { + prgb=ct->clut+i; + if ((di2=DISTANCE(*prgb,rgb))<di) { best=i; - di=DISTANCE(ct->clut[i],rgb); + di=di2; } -#endif + } /* place in cache */ #if QUANT_SELECT_CACHE>1