From b54bd6a0f22a730bab9ab4ba63621a24902baf95 Mon Sep 17 00:00:00 2001 From: "Mirar (Pontus Hagland)" <pike@sort.mirar.org> Date: Sun, 13 Oct 1996 23:08:32 +0200 Subject: [PATCH] minor patches & warnings fixed in lzw.c Rev: src/modules/image/image.c:1.15 Rev: src/modules/image/image.h:1.4 Rev: src/modules/image/lzw.c:1.4 Rev: src/modules/image/quant.c:1.7 Rev: src/modules/image/togif.c:1.7 --- src/modules/image/image.c | 89 +++++++++++++++++++++++++++++++++------ src/modules/image/image.h | 7 +++ src/modules/image/lzw.c | 4 +- src/modules/image/quant.c | 63 ++++++++++++++++++++++++++- src/modules/image/togif.c | 14 +++--- 5 files changed, 153 insertions(+), 24 deletions(-) diff --git a/src/modules/image/image.c b/src/modules/image/image.c index ea81055763..714e038642 100644 --- a/src/modules/image/image.c +++ b/src/modules/image/image.c @@ -1743,7 +1743,7 @@ void image_modify_by_intensity(INT32 args) push_object(o); } -static void image_quant(INT32 args) +static void image_map_closest(INT32 args) { struct colortable *ct; long i; @@ -1751,18 +1751,13 @@ static void image_quant(INT32 args) int colors; if (!THIS->img) error("no image\n"); - if (args>=1) - if (sp[-args].type==T_INT) - colors=sp[-args].u.integer; - else - error("Illegal argument to image->quant()\n"); - else - colors=256; + if (args<1 + || sp[-args].type!=T_ARRAY) + error("illegal argument to image->map_closest()\n"); + ct=colortable_from_array(sp[-args].u.array,"image->map_closest()\n"); pop_n_elems(args); - ct=colortable_quant(THIS,colors); - i=THIS->xsize*THIS->ysize; rgb=THIS->img; while (i--) @@ -1772,9 +1767,75 @@ static void image_quant(INT32 args) } colortable_free(ct); + THISOBJ->refs++; + push_object(THISOBJ); +} + +static void image_map_fs(INT32 args) +{ + struct colortable *ct; + INT32 i,j; + rgb_group *rgb; + int *res,w; + rgbl_group *errb; + + if (!THIS->img) error("no image\n"); + if (args<1 + || sp[-args].type!=T_ARRAY) + error("illegal argument to image->map_fs()\n"); + + res=(int*)xalloc(sizeof(int)*THIS->xsize); + errb=(rgbl_group*)xalloc(sizeof(rgbl_group)*THIS->xsize); + + ct=colortable_from_array(sp[-args].u.array,"image->map_closest()\n"); + pop_n_elems(args); + + for (i=0; i<THIS->xsize; i++) + errb[i].r=(rand()%(FS_SCALE*2+1))-FS_SCALE, + errb[i].g=(rand()%(FS_SCALE*2+1))-FS_SCALE, + errb[i].b=(rand()%(FS_SCALE*2+1))-FS_SCALE; + + i=THIS->ysize; + rgb=THIS->img; + w=0; + while (i--) + { + image_floyd_steinberg(rgb,THIS->xsize,errb,w=!w,res,ct); + for (j=0; j<THIS->xsize; j++) + *(rgb++)=ct->clut[res[j]]; + } + + free(errb); + free(res); + colortable_free(ct); + THISOBJ->refs++; + push_object(THISOBJ); +} + +void image_select_colors(INT32 args) +{ + rgb_group *transparent=NULL; + struct colortable *ct; + int colors,i; + + if (args<1 + || sp[-args].type!=T_INT) + error("Illegal argument to image->select_colors()\n"); + colors=sp[-args].u.integer; pop_n_elems(args); - push_int(0); + if (!THIS->img) { error("no image\n"); return; } + + ct=colortable_quant(THIS,colors); + for (i=0; i<colors; i++) + { + push_int(ct->clut[i].r); + push_int(ct->clut[i].g); + push_int(ct->clut[i].b); + f_aggregate(3); + } + f_aggregate(colors); + colortable_free(ct); } static void image_ccw(INT32 args) @@ -2003,8 +2064,12 @@ void init_image_programs() add_function("ysize",image_ysize, "function(:int)",0); - add_function("quant",image_quant, + add_function("map_closest",image_map_closest, + "function(:object)",0); + add_function("map_fs",image_map_fs, "function(:object)",0); + add_function("select_colors",image_select_colors, + "function(int:array(array(int)))",0); set_init_callback(init_image_struct); set_exit_callback(exit_image_struct); diff --git a/src/modules/image/image.h b/src/modules/image/image.h index ef9b0a4376..fa3359b8d9 100644 --- a/src/modules/image/image.h +++ b/src/modules/image/image.h @@ -7,6 +7,8 @@ #define COLOURTYPE unsigned char +#define FS_SCALE 1024 + typedef struct { COLOURTYPE r,g,b; @@ -48,6 +50,7 @@ struct colortable struct colortable *colortable_quant(struct image *img,int numcol); int colortable_rgb(struct colortable *ct,rgb_group rgb); void colortable_free(struct colortable *ct); +struct colortable *colortable_from_array(struct array *arr,char *from); /* encoding of a gif - from togif */ @@ -55,4 +58,8 @@ struct pike_string * image_encode_gif(struct image *img,struct colortable *ct, rgb_group *transparent, int floyd_steinberg); +void image_floyd_steinberg(rgb_group *rgb,int xsize, + rgbl_group *errl, + int way,int *res, + struct colortable *ct); diff --git a/src/modules/image/lzw.c b/src/modules/image/lzw.c index 035162a321..225fd40c75 100644 --- a/src/modules/image/lzw.c +++ b/src/modules/image/lzw.c @@ -20,7 +20,7 @@ static void lzw_output(struct lzw *lzw,lzwcode_t codeno); void lzw_init(struct lzw *lzw,int bits) { - int i; + unsigned long i; #ifdef GIF_LZW lzw->codes=(1L<<bits)+2; #else @@ -186,7 +186,7 @@ void lzw_add(struct lzw *lzw,int c) l->c=c; lzw->codes++; - if (lzw->codes>(1L<<lzw->codebits)) lzw->codebits++; + if (lzw->codes>(unsigned long)(1L<<lzw->codebits)) lzw->codebits++; lzw->current=lzw->code+c; } diff --git a/src/modules/image/quant.c b/src/modules/image/quant.c index ec7ab286df..21884642a1 100644 --- a/src/modules/image/quant.c +++ b/src/modules/image/quant.c @@ -17,6 +17,7 @@ David K #include "types.h" #include "error.h" #include "global.h" +#include "array.h" #include "image.h" @@ -426,9 +427,8 @@ struct colortable *colortable_quant(struct image *img,int numcol) ct = malloc(sizeof(struct colortable)+sizeof(rgb_group)*numcol); if (!ct) error("Out of memory.\n"); - ct->numcol=numcol; - MEMSET(ct,0,sizeof(struct colortable)+sizeof(rgb_group)*numcol); + ct->numcol=numcol; #ifdef QUANT_DEBUG fprintf(stderr,"Moving colors into hashtable\n"); @@ -509,6 +509,65 @@ struct colortable *colortable_quant(struct image *img,int numcol) return ct; } + +struct colortable *colortable_from_array(struct array *arr,char *from) +{ + rgb_hashtbl *tbl; + INT32 i,j; + coltab *ct; + rgb_group black,white; + rgb_group *p; + INT32 entries=0; + struct svalue s,s2; + +#ifdef QUANT_DEBUG + fprintf(stderr,"ctfa called\n"); +#endif + CHRONO("ctfa"); + + white.r=white.g=white.b=255; + black.r=black.g=black.b=0; + + tbl=img_rehash(NULL,arr->size); + + s2.type=s.type=T_INT; + for (i=0; i<arr->size; i++) + { + array_index(&s,arr,i); + if (s.type!=T_ARRAY || s.u.array->size<3) + { + free(tbl); + error("Illegal type in colorlist, element %d, %s\n",i,from); + } + array_index(&s2,s.u.array,0); + if (s2.type!=T_INT) tbl->tbl[i].rgb.r=0; else tbl->tbl[i].rgb.r=s2.u.integer; + array_index(&s2,s.u.array,1); + if (s2.type!=T_INT) tbl->tbl[i].rgb.g=0; else tbl->tbl[i].rgb.g=s2.u.integer; + array_index(&s2,s.u.array,2); + if (s2.type!=T_INT) tbl->tbl[i].rgb.b=0; else tbl->tbl[i].rgb.b=s2.u.integer; + } + free_svalue(&s); + free_svalue(&s2); + + ct = malloc(sizeof(struct colortable)+sizeof(rgb_group)*arr->size); + if (!ct) { free(tbl); error("Out of memory.\n"); } + MEMSET(ct,0,sizeof(struct colortable)+sizeof(rgb_group)*arr->size); + ct->numcol=arr->size; + + CHRONO("sort"); + sort_tbl(tbl, 0, arr->size, 0, 0, arr->size, -1, ct, black, white); + +#ifdef QUANT_DEBUG + fprintf(stderr,"img_quant done, %d colors selected\n", arr->size); +#endif + CHRONO("done"); + + free(tbl); + CHRONO("really done"); + return ct; +} + + #define sq(x) ((x)*(x)) #define DISTANCE(A,B) \ (sq((A).r-(B).r)+sq((A).g-(B).g)+sq((A).b-(B).b)) diff --git a/src/modules/image/togif.c b/src/modules/image/togif.c index 30c82ee3bf..ecf69c5917 100644 --- a/src/modules/image/togif.c +++ b/src/modules/image/togif.c @@ -29,7 +29,6 @@ static void buf_word( unsigned short w, dynamic_buffer *buf ) low_my_putchar( (w>>8)&0xff, buf ); } -#define FS_SCALE 1024 #define WEIGHT_NEXT(X) (((X)*8)/20) #define WEIGHT_DOWNNEXT(X) (((X)*3)/20) #define WEIGHT_DOWN(X) (((X)*3)/20) @@ -104,10 +103,10 @@ static int floyd_steinberg_add(rgbl_group *errl, return c; } -static void floyd_steinberg(rgb_group *rgb,int xsize, - rgbl_group *errl, - int way,int *res, - struct colortable *ct) +void image_floyd_steinberg(rgb_group *rgb,int xsize, + rgbl_group *errl, + int way,int *res, + struct colortable *ct) { rgbl_group err; int x; @@ -205,12 +204,11 @@ struct pike_string * while (i--) lzw_add(&lzw,colortable_rgb(ct,*(rgb++))); else { - rgbl_group err,*errb; + rgbl_group *errb; rgb_group corgb; int w,*cres,j; errb=(rgbl_group*)xalloc(sizeof(rgbl_group)*img->xsize); cres=(int*)xalloc(sizeof(int)*img->xsize); - err.r=err.g=err.b=0; for (i=0; i<img->xsize; i++) errb[i].r=(rand()%(FS_SCALE*2+1))-FS_SCALE, errb[i].g=(rand()%(FS_SCALE*2+1))-FS_SCALE, @@ -220,7 +218,7 @@ struct pike_string * i=img->ysize; while (i--) { - floyd_steinberg(rgb,img->xsize,errb,w=!w,cres,ct); + image_floyd_steinberg(rgb,img->xsize,errb,w=!w,cres,ct); for (j=0; j<img->xsize; j++) lzw_add(&lzw,cres[j]); rgb+=img->xsize; -- GitLab