|
#include "global.h" |
|
|
|
|
|
|
|
|
#include <math.h> |
#include <ctype.h> |
|
#include "stralloc.h" |
#include "global.h" |
#include "pike_macros.h" |
#include "object.h" |
#include "constants.h" |
#include "interpret.h" |
#include "svalue.h" |
#include "array.h" |
#include "error.h" |
#include "threads.h" |
|
#include "image.h" |
|
extern struct program *image_program; |
#define THIS ((struct image *)(fp->current_storage)) |
#define THISOBJ (fp->current_object) |
|
#define absdiff(a,b) ((a)<(b)?((b)-(a)):((a)-(b))) |
#define min(a,b) ((a)<(b)?(a):(b)) |
#define max(a,b) ((a)<(b)?(b):(a)) |
|
#if 0 |
#include <sys/resource.h> |
#define CHRONO(X) chrono(X) |
|
static void chrono(char *x) |
{ |
struct rusage r; |
static struct rusage rold; |
getrusage(RUSAGE_SELF,&r); |
fprintf(stderr,"%s: %ld.%06ld - %ld.%06ld\n",x, |
r.ru_utime.tv_sec,r.ru_utime.tv_usec, |
|
((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?-1:0) |
+r.ru_utime.tv_sec-rold.ru_utime.tv_sec, |
((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?1000000:0) |
+ r.ru_utime.tv_usec-rold.ru_utime.tv_usec |
); |
|
rold=r; |
} |
#else |
#define CHRONO(X) |
#endif |
|
|
|
#define testrange(x) max(min((x),255),0) |
|
#define apply_alpha(x,y,alpha) \ |
((unsigned char)((y*(255L-(alpha))+x*(alpha))/255L)) |
|
#define set_rgb_group_alpha(dest,src,alpha) \ |
(((dest).r=apply_alpha((dest).r,(src).r,alpha)), \ |
((dest).g=apply_alpha((dest).g,(src).g,alpha)), \ |
((dest).b=apply_alpha((dest).b,(src).b,alpha))) |
|
#define pixel(_img,x,y) ((_img)->img[(x)+(y)*(_img)->xsize]) |
|
#define setpixel(x,y) \ |
(THIS->alpha? \ |
set_rgb_group_alpha(THIS->img[(x)+(y)*THIS->xsize],THIS->rgb,THIS->alpha): \ |
((pixel(THIS,x,y)=THIS->rgb),0)) |
|
#define setpixel_test(x,y) \ |
(((x)<0||(y)<0||(x)>=THIS->xsize||(y)>=THIS->ysize)? \ |
0:(setpixel(x,y),0)) |
|
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 img_clear(rgb_group *dest,rgb_group rgb,INT32 size) |
{ |
if(!size) return; |
THREADS_ALLOW(); |
if(!rgb.r && !rgb.b && !rgb.g) |
MEMSET(dest, 0, size*sizeof(rgb_group)); |
else if((sizeof(rgb.r) == 1) && (rgb.r == rgb.b && rgb.b == rgb.g)) |
MEMSET(dest, rgb.r, size*sizeof(rgb_group)); |
else if(size) |
{ |
int increment = 1; |
rgb_group *from = dest; |
*(dest++)=rgb; |
size--; |
for (; size > increment; size-=increment,dest+=increment) |
{ |
MEMCPY(dest,from,increment*sizeof(rgb_group)); |
if(increment < 1024) increment *= 2; |
} |
if(size>0) MEMCPY(dest,from,size*sizeof(rgb_group)); |
} |
THREADS_DISALLOW(); |
} |
|
void img_box_nocheck(INT32 x1,INT32 y1,INT32 x2,INT32 y2) |
{ |
INT32 x,mod; |
rgb_group *foo,*end,rgb; |
struct image *this; |
|
this=THIS; |
rgb=this->rgb; |
mod=this->xsize-(x2-x1)-1; |
foo=this->img+x1+y1*this->xsize; |
end=this->img+x1+y2*this->xsize; |
|
THREADS_ALLOW(); |
if(!this->alpha) |
{ |
if(!mod) |
img_clear(foo,rgb,end-foo); |
else { |
int length = x2-x1+1, xs=this->xsize, y=y2-y1+1; |
rgb_group *from = foo; |
if(!length) return; |
for(x=0; x<length; x++) *(foo+x) = rgb; |
while(--y) MEMCPY((foo+=xs), from, length*sizeof(rgb_group)); |
} |
} else { |
for (; foo<=end; foo+=mod) for (x=x1; x<=x2; x++,foo++) |
set_rgb_group_alpha(*foo,rgb,this->alpha); |
} |
THREADS_DISALLOW(); |
} |
|
|
void img_blit(rgb_group *dest,rgb_group *src,INT32 width, |
INT32 lines,INT32 moddest,INT32 modsrc) |
{ |
if(width <= 0 || lines <= 0) |
return; |
CHRONO("image_blit begin"); |
|
THREADS_ALLOW(); |
if(!moddest && !modsrc) |
MEMCPY(dest,src,sizeof(rgb_group)*width*lines); |
else |
while (lines--) |
{ |
MEMCPY(dest,src,sizeof(rgb_group)*width); |
dest+=moddest; |
src+=modsrc; |
} |
THREADS_DISALLOW(); |
CHRONO("image_blit end"); |
|
} |
|
void img_crop(struct image *dest, |
struct image *img, |
INT32 x1,INT32 y1, |
INT32 x2,INT32 y2) |
{ |
rgb_group *new; |
INT32 xp,yp,xs,ys; |
|
if (dest->img) { free(dest->img); dest->img=NULL; } |
|
if (x1>x2) x1^=x2,x2^=x1,x1^=x2; |
if (y1>y2) y1^=y2,y2^=y1,y1^=y2; |
|
if (x1==0 && y1==0 && |
img->xsize-1==x2 && img->ysize-1==y2) |
{ |
*dest=*img; |
new=malloc( (x2-x1+1)*(y2-y1+1)*sizeof(rgb_group) + 1); |
if (!new) |
error("Out of memory.\n"); |
THREADS_ALLOW(); |
MEMCPY(new,img->img,(x2-x1+1)*(y2-y1+1)*sizeof(rgb_group)); |
THREADS_DISALLOW(); |
dest->img=new; |
return; |
} |
|
new=malloc( (x2-x1+1)*(y2-y1+1)*sizeof(rgb_group) +1); |
if (!new) |
error("Out of memory.\n"); |
|
img_clear(new,THIS->rgb,(x2-x1+1)*(y2-y1+1)); |
|
dest->xsize=x2-x1+1; |
dest->ysize=y2-y1+1; |
|
xp=max(0,-x1); |
yp=max(0,-y1); |
xs=max(0,x1); |
ys=max(0,y1); |
|
if (x1<0) x1=0; else if (x1>=img->xsize) x1=img->xsize-1; |
if (y1<0) y1=0; else if (y1>=img->ysize) y1=img->ysize-1; |
if (x2<0) x2=0; else if (x2>=img->xsize) x2=img->xsize-1; |
if (y2<0) y2=0; else if (y2>=img->ysize) y2=img->ysize-1; |
|
img_blit(new+xp+yp*dest->xsize, |
img->img+xs+(img->xsize)*ys, |
x2-x1+1, |
y2-y1+1, |
dest->xsize, |
img->xsize); |
|
dest->img=new; |
} |
|
void img_clone(struct image *newimg,struct image *img) |
{ |
if (newimg->img) free(newimg->img); |
newimg->img=malloc(sizeof(rgb_group)*img->xsize*img->ysize +1); |
if (!newimg->img) error("Out of memory!\n"); |
THREADS_ALLOW(); |
MEMCPY(newimg->img,img->img,sizeof(rgb_group)*img->xsize*img->ysize); |
THREADS_DISALLOW(); |
newimg->xsize=img->xsize; |
newimg->ysize=img->ysize; |
newimg->rgb=img->rgb; |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void image_paste(INT32 args) |
{ |
struct image *img; |
INT32 x1,y1,x2,y2,blitwidth,blitheight; |
|
if (args<1 |
|| sp[-args].type!=T_OBJECT |
|| !(img=(struct image*)get_storage(sp[-args].u.object,image_program))) |
error("illegal argument 1 to image->paste()\n"); |
if (!THIS->img) return; |
|
if (!img->img) return; |
|
if (args>1) |
{ |
if (args<3 |
|| sp[1-args].type!=T_INT |
|| sp[2-args].type!=T_INT) |
error("illegal arguments to image->paste()\n"); |
x1=sp[1-args].u.integer; |
y1=sp[2-args].u.integer; |
} |
else x1=y1=0; |
|
if(x1 >= THIS->xsize || y1 >= THIS->ysize) |
{ |
pop_n_elems(args); |
THISOBJ->refs++; |
push_object(THISOBJ); |
return; |
} |
x2=x1+img->xsize-1; |
y2=y1+img->ysize-1; |
|
if(x2 < 0 || y2 < 0) |
{ |
pop_n_elems(args); |
THISOBJ->refs++; |
push_object(THISOBJ); |
return; |
} |
blitwidth=min(x2,THIS->xsize-1)-max(x1,0)+1; |
blitheight=min(y2,THIS->ysize-1)-max(y1,0)+1; |
|
img_blit(THIS->img+max(0,x1)+(THIS->xsize)*max(0,y1), |
img->img+max(0,-x1)+(x2-x1+1)*max(0,-y1), |
blitwidth, |
blitheight, |
THIS->xsize, |
img->xsize); |
|
pop_n_elems(args); |
THISOBJ->refs++; |
push_object(THISOBJ); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void image_paste_alpha(INT32 args) |
{ |
struct image *img; |
INT32 x1,y1; |
|
if (args<2 |
|| sp[-args].type!=T_OBJECT |
|| !sp[-args].u.object |
|| !(img=(struct image*)get_storage(sp[-args].u.object,image_program)) |
|| sp[1-args].type!=T_INT) |
error("illegal arguments to image->paste_alpha()\n"); |
if (!THIS->img) return; |
if (!img->img) return; |
THIS->alpha=(unsigned char)(sp[1-args].u.integer); |
|
if (args>=4) |
{ |
if (sp[2-args].type!=T_INT |
|| sp[3-args].type!=T_INT) |
error("illegal arguments to image->paste_alpha()\n"); |
x1=sp[2-args].u.integer; |
y1=sp[3-args].u.integer; |
} |
else x1=y1=0; |
|
if(x1 >= THIS->xsize || y1 >= THIS->ysize) |
{ |
pop_n_elems(args); |
THISOBJ->refs++; |
push_object(THISOBJ); |
return; |
} |
|
|
|
{ |
rgb_group *source = img->img; |
struct image *this = THIS; |
int xs = this->xsize, ix, mx=img->xsize, my=img->ysize, x; |
int ys = this->ysize, iy, y; |
|
THREADS_ALLOW(); |
for (iy=0; iy<my; iy++) |
for (ix=0; ix<mx; ix++) |
{ |
x = ix + x1; y = iy + y1; |
if(x>=0 && y>=0 && x<xs && y<ys) |
if(this->alpha) |
set_rgb_group_alpha(this->img[x+y*xs],*(source),this->alpha); |
else |
this->img[x+y*xs]=*(source); |
source++; |
} |
THREADS_DISALLOW(); |
} |
pop_n_elems(args); |
THISOBJ->refs++; |
push_object(THISOBJ); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void image_paste_mask(INT32 args) |
{ |
struct image *img,*mask; |
INT32 x1,y1,x,y,x2,y2,smod,dmod,mmod; |
rgb_group *s,*d,*m; |
float q; |
|
CHRONO("image_paste_mask init"); |
|
if (args<2) |
error("illegal number of arguments to image->paste_mask()\n"); |
if (sp[-args].type!=T_OBJECT |
|| !(img=(struct image*)get_storage(sp[-args].u.object,image_program))) |
error("illegal argument 1 to image->paste_mask()\n"); |
if (sp[1-args].type!=T_OBJECT |
|| !(mask=(struct image*)get_storage(sp[1-args].u.object,image_program))) |
error("illegal argument 2 to image->paste_mask()\n"); |
if (!THIS->img) return; |
|
if (!mask->img) return; |
if (!img->img) return; |
|
if (args>=4) |
{ |
if (sp[2-args].type!=T_INT |
|| sp[3-args].type!=T_INT) |
error("illegal coordinate arguments to image->paste_mask()\n"); |
x1=sp[2-args].u.integer; |
y1=sp[3-args].u.integer; |
} |
else x1=y1=0; |
|
x2=min(THIS->xsize-x1,min(img->xsize,mask->xsize)); |
y2=min(THIS->ysize-y1,min(img->ysize,mask->ysize)); |
|
CHRONO("image_paste_mask begin"); |
|
s=img->img+max(0,-x1)+max(0,-y1)*img->xsize; |
m=mask->img+max(0,-x1)+max(0,-y1)*mask->xsize; |
d=THIS->img+max(0,-x1)+x1+(y1+max(0,-y1))*THIS->xsize; |
x=max(0,-x1); |
smod=img->xsize-(x2-x); |
mmod=mask->xsize-(x2-x); |
dmod=THIS->xsize-(x2-x); |
|
q=1.0/255; |
|
THREADS_ALLOW(); |
for (y=max(0,-y1); y<y2; y++) |
{ |
for (x=max(0,-x1); x<x2; x++) |
{ |
if (m->r==255) d->r=s->r; |
else if (m->r==0) {} |
else d->r=(unsigned char)(((d->r*(255-m->r))+(s->r*m->r))*q); |
if (m->g==255) d->g=s->g; |
else if (m->g==0) {} |
else d->g=(unsigned char)(((d->g*(255-m->g))+(s->g*m->g))*q); |
if (m->b==255) d->b=s->b; |
else if (m->b==0) {} |
else d->b=(unsigned char)(((d->b*(255-m->b))+(s->b*m->b))*q); |
s++; m++; d++; |
} |
s+=smod; m+=mmod; d+=dmod; |
} |
THREADS_DISALLOW(); |
CHRONO("image_paste_mask end"); |
|
pop_n_elems(args); |
THISOBJ->refs++; |
push_object(THISOBJ); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void image_paste_alpha_color(INT32 args) |
{ |
struct image *mask; |
INT32 x1,y1,x,y,x2,y2; |
rgb_group rgb,*d,*m; |
INT32 mmod,dmod; |
float q; |
|
if (args!=1 && args!=4 && args!=6 && args!=3) |
error("illegal number of arguments to image->paste_alpha_color()\n"); |
if (sp[-args].type!=T_OBJECT |
|| !sp[-args].u.object |
|| !(mask=(struct image*)get_storage(sp[-args].u.object,image_program))) |
error("illegal argument 1 to image->paste_alpha_color()\n"); |
if (!THIS->img) return; |
if (!mask->img) return; |
|
if (args==6 || args==4) |
getrgb(THIS,1,args,"image->paste_alpha_color()\n"); |
if (args==3) |
{ |
if (sp[1-args].type!=T_INT |
|| sp[2-args].type!=T_INT) |
error("illegal coordinate arguments to image->paste_alpha_color()\n"); |
x1=sp[1-args].u.integer; |
y1=sp[2-args].u.integer; |
} |
else if (args==6) |
{ |
if (sp[4-args].type!=T_INT |
|| sp[5-args].type!=T_INT) |
error("illegal coordinate arguments to image->paste_alpha_color()\n"); |
x1=sp[4-args].u.integer; |
y1=sp[5-args].u.integer; |
} |
else x1=y1=0; |
|
x2=min(THIS->xsize-x1,mask->xsize); |
y2=min(THIS->ysize-y1,mask->ysize); |
|
CHRONO("image_paste_alpha_color begin"); |
|
m=mask->img+max(0,-x1)+max(0,-y1)*mask->xsize; |
d=THIS->img+max(0,-x1)+x1+(y1+max(0,-y1))*THIS->xsize; |
x=max(0,-x1); |
mmod=mask->xsize-(x2-x); |
dmod=THIS->xsize-(x2-x); |
|
q=1.0/255; |
|
rgb=THIS->rgb; |
|
THREADS_ALLOW(); |
for (y=max(0,-y1); y<y2; y++) |
{ |
for (x=max(0,-x1); x<x2; x++) |
{ |
if (m->r==255) d->r=rgb.r; |
else if (m->r==0) ; |
else d->r=(unsigned char)(((d->r*(255-m->r))+(rgb.r*m->r))*q); |
if (m->g==255) d->g=rgb.g; |
else if (m->g==0) ; |
else d->g=(unsigned char)(((d->g*(255-m->g))+(rgb.g*m->g))*q); |
if (m->b==255) d->b=rgb.b; |
else if (m->b==0) ; |
else d->b=(unsigned char)(((d->b*(255-m->b))+(rgb.b*m->b))*q); |
m++; d++; |
} |
m+=mmod; d+=dmod; |
} |
THREADS_DISALLOW(); |
CHRONO("image_paste_alpha_color end"); |
|
pop_n_elems(args); |
THISOBJ->refs++; |
push_object(THISOBJ); |
} |
|
void img_box(INT32 x1,INT32 y1,INT32 x2,INT32 y2) |
{ |
if (x1>x2) x1^=x2,x2^=x1,x1^=x2; |
if (y1>y2) y1^=y2,y2^=y1,y1^=y2; |
if (x2 >= THIS->xsize) x2 = THIS->xsize-1; |
if (y2 >= THIS->ysize) y2 = THIS->ysize-1; |
if (x2<0||y2<0||x1>=THIS->xsize||y1>=THIS->ysize) return; |
if (x1<0) x1 = 0; |
if (y1<0) y1 = 0; |
img_box_nocheck(max(x1,0),max(y1,0),min(x2,THIS->xsize-1),min(y2,THIS->ysize-1)); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void image_add_layers(INT32 args) |
|
|
|
|
|
|
|
|
|
{ |
struct img_layer |
{ |
rgb_group *s; |
rgb_group *m; |
int opaque; |
enum layer_method method; |
} *layer; |
float q2=1/(255.0*255.0); |
float q=1/(255.0); |
rgb_group *s; |
rgb_group *d; |
struct object *o; |
|
int allopaque255=1,allmask=1,allnop=1; |
|
int i,j,l,mod,layers; |
int x1,y1,x2,y2; |
|
if (!THIS->img) error("No image."); |
s=THIS->img; |
|
if (args>=4 |
&& sp[-args].type==T_INT |
&& sp[1-args].type==T_INT |
&& sp[2-args].type==T_INT |
&& sp[3-args].type==T_INT) |
{ |
x1=sp[-args].u.integer; |
y1=sp[1-args].u.integer; |
x2=sp[2-args].u.integer; |
y2=sp[3-args].u.integer; |
|
if (x2<x1) x2^=x1,x1^=x2,x2^=x1; |
if (y2<y1) y2^=y1,y1^=y2,y2^=y1; |
|
if (x2>THIS->xsize-1 || |
y2>THIS->ysize-1 || |
x1<0 || y1<0) |
error("Illegal coordinates to image->add_layers()\n"); |
layers=args-4; |
} |
else |
{ |
x1=0; |
y1=0; |
x2=THIS->xsize-1; |
y2=THIS->ysize-1; |
layers=args; |
} |
|
layer=(struct img_layer*)xalloc(sizeof(struct img_layer)*layers); |
|
for (j=0,i=layers; i>0; i--,j++) |
{ |
struct array *a; |
struct image *img; |
if (sp[-i].type!=T_ARRAY) |
{ |
free(layer); |
error("Illegal argument(s) to image->add_layers()\n"); |
} |
a=sp[-i].u.array; |
if (a->size<2) |
{ |
free(layer); |
error("Illegal size of array argument to image->add_layers()\n"); |
} |
|
if (a->item[0].type!=T_OBJECT) |
{ |
free(layer); |
error("Illegal array contents, layer %d (argument %d) (wrong or no image) to image->add_layers()\n",layers-i,args-i+1); |
} |
img=(struct image*)get_storage(a->item[0].u.object,image_program); |
if (!img |
|| !img->img |
|| img->xsize != THIS->xsize |
|| img->ysize != THIS->ysize) |
{ |
free(layer); |
error("Illegal array contents, layer %d (argument %d) (no image or wrong image size) to image->add_layers()\n",layers-i,args-i+1); |
} |
layer[j].s=img->img; |
|
if (a->item[1].type==T_INT |
&& a->item[1].u.integer==0) |
{ |
layer[j].m=NULL; |
} |
else |
{ |
if (a->item[1].type!=T_OBJECT) |
{ |
free(layer); |
error("Illegal array contents, layer %d (argument %d) (wrong or no image for mask) to image->add_layers()\n",layers-i,args-i+1); |
} |
img=(struct image*)get_storage(a->item[1].u.object,image_program); |
if (!img |
|| !img->img |
|| img->xsize != THIS->xsize |
|| img->ysize != THIS->ysize) |
{ |
free(layer); |
error("Illegal array contents, layer %d (argument %d) (no mask or wrong mask size) to image->add_layers()\n",layers-i,args-i+1); |
} |
layer[j].m=img->img; |
} |
|
if (a->size>=3) |
{ |
if (a->item[2].type!=T_INT) |
{ |
free(layer); |
error("Illegal array contents, layer %d (argument %d) (illegal opaque) to image->add_layers()\n",layers-i,args-i+1); |
} |
layer[j].opaque=a->item[2].u.integer; |
} |
else |
layer[j].opaque=255; |
|
if (a->size>=4) |
{ |
if (a->item[3].type!=T_INT) |
{ |
free(layer); |
error("Illegal array contents, layer %d (argument %d) (illegal method) to image->add_layers()\n",layers-i,args-i+1); |
} |
layer[j].method=(enum layer_method)a->item[3].u.integer; |
} |
else |
layer[j].method=LAYER_NOP; |
} |
|
push_int(1+x2-x1); |
push_int(1+y2-y1); |
o=clone_object(image_program,2); |
d=((struct image*)get_storage(o,image_program))->img; |
|
|
mod=THIS->xsize-(x2-x1+1); |
s+=x1+THIS->xsize*y1; |
for (i=0; i<layers; i++) |
{ |
layer[i].s+=x1+THIS->xsize*y1; |
if (layer[i].m) layer[i].m+=x1+THIS->xsize*y1; |
else allmask=0; |
if (layer[i].opaque!=255) allopaque255=0; |
if (layer[i].method!=LAYER_NOP) allnop=0; |
} |
|
if (allmask && allopaque255 && allnop) |
{ |
#define ALL_IS_NOP |
#define ALL_HAVE_MASK |
#define ALL_HAVE_OPAQUE |
#include "blit_layer_include.h" |
#undef ALL_IS_NOP |
#undef ALL_HAVE_MASK |
#undef ALL_HAVE_OPAQUE |
} |
else if (allopaque255 && allnop) |
{ |
#define ALL_IS_NOP |
#define ALL_HAVE_OPAQUE |
#include "blit_layer_include.h" |
#undef ALL_IS_NOP |
#undef ALL_HAVE_OPAQUE |
} |
else if (allmask && allnop) |
{ |
#define ALL_HAVE_MASK |
#define ALL_HAVE_OPAQUE |
#include "blit_layer_include.h" |
#undef ALL_HAVE_MASK |
#undef ALL_HAVE_OPAQUE |
} |
else if (allnop) |
{ |
#define ALL_IS_NOP |
#include "blit_layer_include.h" |
#undef ALL_IS_NOP |
} |
else if (allmask && allopaque255) |
{ |
#define ALL_HAVE_MASK |
#define ALL_HAVE_OPAQUE |
#include "blit_layer_include.h" |
#undef ALL_HAVE_MASK |
#undef ALL_HAVE_OPAQUE |
} |
else if (allopaque255) |
{ |
#define ALL_HAVE_OPAQUE |
#include "blit_layer_include.h" |
#undef ALL_HAVE_OPAQUE |
} |
else if (allmask) |
{ |
#define ALL_HAVE_MASK |
#include "blit_layer_include.h" |
#undef ALL_HAVE_MASK |
} |
else |
{ |
#include "blit_layer_include.h" |
} |
|
|
pop_n_elems(args); |
|
free(layer); |
|
push_object(o); |
} |
|
|