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);