|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "global.h" |
|
#include <math.h> |
#include <ctype.h> |
|
#include "stralloc.h" |
#include "global.h" |
#include "threads.h" |
#include "pike_macros.h" |
#include "object.h" |
#include "constants.h" |
#include "interpret.h" |
#include "svalue.h" |
#include "array.h" |
#include "error.h" |
#include "dynamic_buffer.h" |
#include "operators.h" |
|
#include "image.h" |
|
#define THIS ((struct image *)(fp->current_storage)) |
#define THISOBJ (fp->current_object) |
|
extern struct program *image_colortable_program; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern void image_gif_header_block(INT32 args); |
extern void image_gif_end_block(INT32 args); |
extern void image_gif_netscape_loop_block(INT32 args); |
|
void image_gif_begin(INT32 args) |
{ |
if (args) |
{ |
struct object *o; |
if (sp[-args].type==T_INT) |
{ |
int i=sp[-args].u.integer; |
pop_n_elems(args); |
push_int(THIS->xsize); |
push_int(THIS->ysize); |
THISOBJ->refs++; |
push_object(THISOBJ); |
push_int(i); |
o=clone_object(image_colortable_program,2); |
} |
else |
{ |
o=clone_object(image_colortable_program,args); |
} |
push_int(THIS->xsize); |
push_int(THIS->ysize); |
push_object(o); |
image_gif_header_block(3); |
} |
else |
{ |
push_int(THIS->xsize); |
push_int(THIS->ysize); |
push_int(256); |
image_gif_header_block(3); |
} |
} |
|
void image_gif_end(INT32 args) |
{ |
image_gif_end_block(args); |
} |
|
void image_gif_netscape_loop(INT32 args) |
{ |
image_gif_netscape_loop_block(args); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void img_gif_add(INT32 args,int fs,int lm, |
rgb_group *transparent) |
{ |
INT32 x=0,y=0; |
int delay=0; |
struct object *ncto=NULL; |
|
if (args==0) x=y=0; |
else if (args<2 |
|| 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) |
{ |
struct svalue *sv=sp+2-args; |
push_svalue(sv); |
ncto=clone_object(image_colortable_program,2); |
} |
else if (args>3 && sp[2-args].type==T_INT) |
{ |
INT32 i=sp[2-args].u.integer; |
THISOBJ->refs++; |
push_object(THISOBJ); |
push_int(i); |
ncto=clone_object(image_colortable_program,2); |
} |
|
if (args>2+!!ncto) |
{ |
if (sp[2+!!ncto-args].type==T_INT) |
delay=sp[2+!!ncto-args].u.integer; |
else if (sp[2+!!ncto-args].type==T_FLOAT) |
delay=(unsigned short)(sp[2+!!ncto-args].u.float_number*100); |
else |
error("Illegal argument %d to image->gif_add()\n",3+!!ncto); |
} |
|
if (!ncto) |
{ |
THISOBJ->refs++; |
push_object(THISOBJ); |
push_int(256); |
ncto=clone_object(image_colortable_program,2); |
} |
|
if (fs) image_colortable_internal_floyd_steinberg( |
get_storage(ncto,image_colortable_program)); |
|
pop_n_elems(args); |
|
THISOBJ->refs++; |
push_object(THISOBJ); |
push_object(ncto); |
push_int(x); |
push_int(y); |
push_int(lm); |
push_int(delay); |
|
if (transparent) |
{ |
unsigned char trd; |
|
image_colortable_index_8bit_image(get_storage(ncto, |
image_colortable_program), |
transparent,&trd,1,1); |
|
push_int(trd); |
|
image_gif_render_block(7); |
} |
else |
image_gif_render_block(6); |
} |
|
|
void image_gif_add(INT32 args) |
{ |
img_gif_add(args,0,1,NULL); |
} |
|
void image_gif_add_fs(INT32 args) |
{ |
img_gif_add(args,1,1,NULL); |
} |
|
void image_gif_add_nomap(INT32 args) |
{ |
img_gif_add(args,0,0,NULL); |
} |
|
void image_gif_add_fs_nomap(INT32 args) |
{ |
img_gif_add(args,1,0,NULL); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void img_encode_gif(rgb_group *transparent,int fs,INT32 args) |
{ |
struct svalue sv; |
|
|
|
|
|
push_int(0); if (args) { sv=sp[-1]; sp[-1]=sp[-2]; sp[-2]=sv; } |
push_int(0); if (args) { sv=sp[-1]; sp[-1]=sp[-2]; sp[-2]=sv; } |
|
img_gif_add(args+2,fs,1,transparent); |
image_gif_begin(0); |
|
|
|
|
|
|
sv=sp[-1]; sp[-1]=sp[-2]; sp[-2]=sv; |
|
image_gif_end(0); |
|
|
|
|
|
|
f_add(3); |
} |
|
static INLINE void getrgb(struct image *img, |
INT32 args_start,INT32 args,char *name) |
{ |
INT32 i; |
if (args-args_start<3) return; |
for (i=0; i<3; i++) |
if (sp[-args+i+args_start].type!=T_INT) |
error("Illegal r,g,b argument to %s\n",name); |
img->rgb.r=(unsigned char)sp[-args+args_start].u.integer; |
img->rgb.g=(unsigned char)sp[1-args+args_start].u.integer; |
img->rgb.b=(unsigned char)sp[2-args+args_start].u.integer; |
if (args-args_start>=4) |
if (sp[3-args+args_start].type!=T_INT) |
error("Illegal alpha argument to %s\n",name); |
else |
img->alpha=sp[3-args+args_start].u.integer; |
else |
img->alpha=0; |
} |
|
void image_togif(INT32 args) |
{ |
rgb_group *transparent=NULL; |
|
if (args>=3) |
{ |
getrgb(THIS,args>3,args,"image->togif() (transparency)"); |
transparent=&(THIS->rgb); |
} |
if (args==3) pop_n_elems(3); |
else if (args) pop_n_elems(args-1); |
|
if (!THIS->img) { error("no image\n"); return; } |
|
img_encode_gif(transparent, 0, args&&args!=3); |
} |
|
|
void image_togif_fs(INT32 args) |
{ |
rgb_group *transparent=NULL; |
|
if (args>=3) |
{ |
getrgb(THIS,args>3,args,"image->togif() (transparency)"); |
transparent=&(THIS->rgb); |
} |
if (args==3) pop_n_elems(3); |
else if (args) pop_n_elems(args-1); |
|
if (!THIS->img) { error("no image\n"); return; } |
|
img_encode_gif(transparent, 1, args&&args!=3); |
} |
|
|