pike.git / src / modules / Image / togif.c

version» Context lines:

pike.git/src/modules/Image/togif.c:1:   /*      togif      Pontus Hagland, law@infovav.se    - $Id: togif.c,v 1.2 1997/03/17 03:08:02 hubbe Exp $ + $Id: togif.c,v 1.3 1997/03/18 17:23:21 mirar Exp $      */      #include "global.h"      #include <math.h>   #include <ctype.h>      #include "stralloc.h"   #include "global.h"
pike.git/src/modules/Image/togif.c:62:   #define min(a,b) ((a)<(b)?(a):(b))   #define max(a,b) ((a)<(b)?(b):(a))   #define testrange(x) max(min((x),255),0)      static void buf_word( unsigned short w, dynamic_buffer *buf )   {    low_my_putchar( w&0xff, buf );    low_my_putchar( (w>>8)&0xff, buf );   }    - #define WEIGHT_NEXT(X) (((X)*8)/20) + #define WEIGHT_NEXT(X) (((X)*8)/20)   #define WEIGHT_DOWNNEXT(X) (((X)*3)/20) - #define WEIGHT_DOWN(X) (((X)*3)/20) + #define WEIGHT_DOWN(X) (((X)*3)/20)   #define WEIGHT_DOWNBACK(X) (((X)*0)/20)      static int floyd_steinberg_add(rgbl_group *errl,    rgbl_group *errlfwd,    rgbl_group *errlback,    rgbl_group *err,    rgb_group rgb, -  struct colortable *ct) +  struct colortable *ct, +  int closest)   {    rgb_group rgb2,rgb3;    rgbl_group cerr;    int c;    rgb2.r=testrange((long)rgb.r+err->r/FS_SCALE);    rgb2.g=testrange((long)rgb.g+err->g/FS_SCALE);    rgb2.b=testrange((long)rgb.b+err->b/FS_SCALE);   #ifdef FS_DEBUG    fprintf(stderr,"%g,%g,%g+%g,%g,%g=%g,%g,%g ",    1.0*rgb.r, 1.0*rgb.g, 1.0*rgb.b,    err->r*1.0/FS_SCALE, err->g*1.0/FS_SCALE, err->b*1.0/FS_SCALE,    rgb2.r*1.0, rgb2.g*1.0, rgb2.b*1.0);   #endif -  +  if (closest) +  c=colortable_rgb_closest(ct,rgb2); +  else    c=colortable_rgb(ct,rgb2);    rgb3=ct->clut[c];    cerr.r=(long)rgb.r*FS_SCALE-(long)rgb3.r*FS_SCALE+err->r;    cerr.g=(long)rgb.g*FS_SCALE-(long)rgb3.g*FS_SCALE+err->g;    cerr.b=(long)rgb.b*FS_SCALE-(long)rgb3.b*FS_SCALE+err->b;      #ifdef FS_DEBUG    fprintf(stderr,"got %g,%g,%g err %g,%g,%g ",    1.0*rgb3.r,    1.0*rgb3.g,
pike.git/src/modules/Image/togif.c:139: Inside #if defined(FS_DEBUG)
  #ifdef FS_DEBUG    fprintf(stderr,"errl=>%g ",errl->g*1.0/FS_SCALE);    fprintf(stderr,"err=>%g\n",err->g*1.0/FS_SCALE);   #endif    return c;   }      void image_floyd_steinberg(rgb_group *rgb,int xsize,    rgbl_group *errl,    int way,int *res, -  struct colortable *ct) +  struct colortable *ct, +  int closest)   {    rgbl_group err;    int x;       if (way)    {    err.r=errl[xsize-1].r;    err.g=errl[xsize-1].g;    err.b=errl[xsize-1].b;    for (x=xsize-1; x>=0; x--)    res[x]=floyd_steinberg_add(errl+x,    (x==0)?NULL:errl+x-1,    (x==xsize-1)?NULL:errl+x+1, -  &err,rgb[x],ct); +  &err,rgb[x],ct,closest);    }    else    {    err.r=errl->r;    err.g=errl->g;    err.b=errl->b;    for (x=0; x<xsize; x++)    res[x]=floyd_steinberg_add(errl+x,    (x==xsize-1)?NULL:errl+x+1,    (x==0)?NULL:errl+x-1, -  &err,rgb[x],ct); +  &err,rgb[x],ct,closest);    }   }         struct pike_string *    image_encode_gif(struct image *img,struct colortable *ct, -  rgb_group *transparent,int fs) +  rgb_group *transparent,int fs,int closest)   {    dynamic_buffer buf;    long i;    rgb_group *rgb;    struct lzw lzw;    int colors,bpp;      CHRONO("image_encode_gif begin");       buf.s.str=NULL;
pike.git/src/modules/Image/togif.c:264:    cres=(int*)xalloc(sizeof(int)*img->xsize);    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,    errb[i].b=(rand()%(FS_SCALE*2+1))-FS_SCALE;       w=0;    i=img->ysize;    while (i--)    { -  image_floyd_steinberg(rgb,img->xsize,errb,w=!w,cres,ct); +  image_floyd_steinberg(rgb,img->xsize,errb,w=!w,cres,ct,closest);    for (j=0; j<img->xsize; j++)    lzw_add(&lzw,cres[j]);    rgb+=img->xsize;    }       free(errb);    free(cres);    }       lzw_write_last(&lzw);
pike.git/src/modules/Image/togif.c:490:    if (args>=3+!!ct)    {    getrgb(THIS,!!ct,args,"image->togif() (transparency)");    transparent=&(THIS->rgb);    }       pop_n_elems(args);    if (!THIS->img) { error("no image\n"); return; }       if (!ct) ct=colortable_quant(THIS,256); -  push_string( image_encode_gif( THIS,ct, transparent, 0) ); +  push_string( image_encode_gif( THIS,ct, transparent, 0, 0) );    colortable_free(ct);   }         void image_togif_fs(INT32 args)   {    rgb_group *transparent=NULL;    struct colortable *ct=NULL; -  +  int closest=0;       if (args>0 && sp[-args].type==T_ARRAY) -  +  {    ct=colortable_from_array(sp[-args].u.array,"image->togif_fs()\n"); -  +  closest=1; +  }    else if (args>0 && args!=3 && sp[-args].type==T_INT)    ct=colortable_quant(THIS,min(256,max(2,sp[-args].u.integer)));       if (args>=3+!!ct)    {    getrgb(THIS,!!ct,args,"image->togif() (transparency)");    transparent=&(THIS->rgb);    }       pop_n_elems(args);    if (!THIS->img) { error("no image\n"); return; }       if (!ct)    ct=colortable_quant(THIS,256); -  push_string( image_encode_gif( THIS,ct, transparent, 1) ); +  push_string( image_encode_gif( THIS,ct, transparent, 1, closest) );    colortable_free(ct);   }      void image_gif_begin(INT32 args)   {    dynamic_buffer buf;    long i;    int colors,bpp;    struct colortable *ct=NULL;   
pike.git/src/modules/Image/togif.c:610:   }      static void img_gif_add(INT32 args,int fs,int lm)   {    INT32 x=0,y=0,i;    struct lzw lzw;    rgb_group *rgb;    struct colortable *ct=NULL;    dynamic_buffer buf;    int colors,bpp; +  int closest;      CHRONO("gif add init");       buf.s.str=NULL;    initialize_buf(&buf);       if (args==0) x=y=0;    else if (sp[-args].type!=T_INT    || sp[1-args].type!=T_INT)    error("Illegal argument(s) to image->gif_add()\n");    else    {    x=sp[-args].u.integer;    y=sp[1-args].u.integer;    }          if (args>2 && sp[2-args].type==T_ARRAY) -  +  {    ct=colortable_from_array(sp[2-args].u.array,"image->gif_add()\n"); -  +  closest=1; +  }    else if (args>3 && sp[2-args].type==T_INT) -  +  {    ct=colortable_quant(THIS,max(256,min(2,sp[2-args].u.integer))); -  +  closest=0; +  }       if (args>2+!!ct)    {    unsigned short delay=0;    if (sp[2+!!ct-args].type==T_INT)    delay=sp[2+!!ct-args].u.integer;    else if (sp[2+!!ct-args].type==T_FLOAT)    delay=(unsigned short)(sp[2+!!ct-args].u.float_number*100);    else    error("Illegal argument %d to image->gif_add()\n",3+!!ct);
pike.git/src/modules/Image/togif.c:714:    cres=(int*)xalloc(sizeof(int)*THIS->xsize);    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;       w=0;    i=THIS->ysize;    while (i--)    { -  image_floyd_steinberg(rgb,THIS->xsize,errb,w=!w,cres,ct); +  image_floyd_steinberg(rgb,THIS->xsize,errb,w=!w,cres,ct,closest);    for (j=0; j<THIS->xsize; j++)    lzw_add(&lzw,cres[j]);    rgb+=THIS->xsize;    }       free(errb);    free(cres);    }       lzw_write_last(&lzw);