diff --git a/src/modules/Image/layer_oper.h b/src/modules/Image/layer_oper.h new file mode 100644 index 0000000000000000000000000000000000000000..70e4210f892c5cc0297866944a906f36ebf85f65 --- /dev/null +++ b/src/modules/Image/layer_oper.h @@ -0,0 +1,64 @@ +/* template for operator layer row function */ + +static void LM_FUNC(rgb_group *s,rgb_group *l,rgb_group *d, + rgb_group *sa,rgb_group *la,rgb_group *da, + int len,float alpha) +{ + if (alpha==0.0) + { + MEMCPY(s,d,sizeof(rgb_group)*len); + MEMCPY(sa,da,sizeof(rgb_group)*len); + return; + } + else if (alpha==1.0) + { + if (!la) /* no layer alpha => full opaque */ + while (len--) + { + d->r=L_TRUNC(L_OPER(COMBINE(s->r,sa->r),l->r)); + d->g=L_TRUNC(L_OPER(COMBINE(s->g,sa->g),l->g)); + d->b=L_TRUNC(L_OPER(COMBINE(s->b,sa->b),l->b)); + *da=white; + l++; s++; sa++; da++; d++; + } + else + while (len--) + { + d->r=L_TRUNC(L_OPER(COMBINE(s->r,sa->r),COMBINE(l->r,la->r))); + d->g=L_TRUNC(L_OPER(COMBINE(s->g,sa->g),COMBINE(l->g,la->g))); + d->b=L_TRUNC(L_OPER(COMBINE(s->b,sa->b),COMBINE(l->b,la->b))); + da->r=COMBINE_ALPHA_SUM(la->r,sa->r); + da->g=COMBINE_ALPHA_SUM(la->g,sa->g); + da->b=COMBINE_ALPHA_SUM(la->b,sa->b); + l++; s++; la++; sa++; da++; d++; + } + } + else + { + if (!la) /* no layer alpha => full opaque */ + while (len--) + { + d->r=L_TRUNC(L_OPER(COMBINE(s->r,sa->r),COMBINE_A(l->r,alpha))); + d->g=L_TRUNC(L_OPER(COMBINE(s->g,sa->g),COMBINE_A(l->g,alpha))); + d->b=L_TRUNC(L_OPER(COMBINE(s->b,sa->b),COMBINE_A(l->b,alpha))); + da->r=COMBINE_ALPHA_SUM_V(COLORMAX,sa->r,alpha); + da->g=COMBINE_ALPHA_SUM_V(COLORMAX,sa->g,alpha); + da->b=COMBINE_ALPHA_SUM_V(COLORMAX,sa->b,alpha); + l++; s++; sa++; da++; d++; + } + else + while (len--) + { + d->r=L_TRUNC(L_OPER(COMBINE(s->r,sa->r), + COMBINE_V(l->r,la->r,alpha))); + d->g=L_TRUNC(L_OPER(COMBINE(s->g,sa->g), + COMBINE_V(l->g,la->g,alpha))); + d->b=L_TRUNC(L_OPER(COMBINE(s->g,sa->b), + COMBINE_V(l->b,la->b,alpha))); + da->r=COMBINE_ALPHA_SUM_V(la->r,sa->r,alpha); + da->g=COMBINE_ALPHA_SUM_V(la->g,sa->g,alpha); + da->b=COMBINE_ALPHA_SUM_V(la->b,sa->b,alpha); + l++; s++; la++; sa++; da++; d++; + } + } +} diff --git a/src/modules/Image/layers.c b/src/modules/Image/layers.c index 9e63a52f95f3bfd76dddc8499e27daead951f984..8aedf24b67c107a57628f3769ebceebe93b31711 100644 --- a/src/modules/Image/layers.c +++ b/src/modules/Image/layers.c @@ -1,14 +1,14 @@ /* **! module Image **! note -**! $Id: layers.c,v 1.5 1999/04/19 18:45:09 mirar Exp $ +**! $Id: layers.c,v 1.6 1999/04/21 23:42:01 mirar Exp $ **! class Layer */ #include "global.h" #include <config.h> -RCSID("$Id: layers.c,v 1.5 1999/04/19 18:45:09 mirar Exp $"); +RCSID("$Id: layers.c,v 1.6 1999/04/21 23:42:01 mirar Exp $"); #include "config.h" @@ -84,60 +84,33 @@ struct layer #define THIS ((struct layer *)(fp->current_storage)) #define THISOBJ (fp->current_object) -static void lm_normal(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_dissolve(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_behind(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_multiply(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_screen(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_overlay(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_difference(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_add(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_subtract(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_darken(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_lighten(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_hue(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_saturation(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_color(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_value(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_divide(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_erase(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); -static void lm_replace(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha); +#define LMFUNC(X) \ + static void X(rgb_group *s,rgb_group *l,rgb_group *d, \ + rgb_group *sa,rgb_group *la,rgb_group *da, \ + int len,float alpha) + +LMFUNC(lm_normal); +LMFUNC(lm_add); +LMFUNC(lm_subtract); +LMFUNC(lm_multiply); +LMFUNC(lm_divide); +LMFUNC(lm_modulo); +LMFUNC(lm_invsubtract); +LMFUNC(lm_invdivide); +LMFUNC(lm_invmodulo); +LMFUNC(lm_dissolve); +LMFUNC(lm_behind); +LMFUNC(lm_screen); +LMFUNC(lm_overlay); +LMFUNC(lm_difference); +LMFUNC(lm_darken); +LMFUNC(lm_lighten); +LMFUNC(lm_hue); +LMFUNC(lm_saturation); +LMFUNC(lm_color); +LMFUNC(lm_value); +LMFUNC(lm_erase); +LMFUNC(lm_replace); struct layer_mode_desc { @@ -150,9 +123,15 @@ struct layer_mode_desc {"normal", lm_normal, 1, NULL }, {"add", lm_add, 1, NULL }, {"subtract", lm_subtract, 1, NULL }, + {"multiply", lm_multiply, 1, NULL }, + {"divide", lm_divide, 1, NULL }, + {"modulo", lm_modulo, 1, NULL }, + {"invsubtract", lm_invsubtract, 1, NULL }, + {"invdivide", lm_invdivide, 1, NULL }, + {"invmodulo", lm_invmodulo, 1, NULL }, + {"dissolve", lm_dissolve, 1, NULL }, /* {"behind", lm_behind, 1, NULL }, */ -/* {"multiply", lm_multiply, 1, NULL }, */ /* {"screen", lm_screen, 1, NULL }, */ /* {"overlay", lm_overlay, 1, NULL }, */ /* {"difference", lm_difference, 1, NULL }, */ @@ -162,7 +141,6 @@ struct layer_mode_desc /* {"saturation", lm_saturation, 1, NULL }, */ /* {"color", lm_color, 1, NULL }, */ /* {"value", lm_value, 1, NULL }, */ -/* {"divide", lm_divide, 1, NULL }, */ /* {"erase", lm_erase, 1, NULL }, */ /* {"replace", lm_replace, 1, NULL }, */ } ; @@ -189,7 +167,19 @@ multiply Pd=Ps*Pl Ad=(Al+(1-Al)*As) divide Pd=Ps/Pl - Ad=As + Ad=(Al+(1-Al)*As) + +invmodulo Pd=Ps%Pl (measured in color values) + Ad=(Al+(1-Al)*As) + +invsubtract Pd=Pl*Al-Ps + Ad=(Al+(1-Al)*As) + +invdivide Pd=Pl/Ps + Ad=(Al+(1-Al)*As) + +invmodulo Pd=Pl%Ps (measured in color values) + Ad=(Al+(1-Al)*As) dissolve i=round(random(Al)) typ Pd=Al*i+As*(1-i) @@ -873,8 +863,10 @@ static void image_layer_cast(INT32 args) #define COMBINE_METHOD_INT #define CCUT_METHOD_INT -#ifdef CCUT_METHOD_FLOAT #define qMAX (1.0/COLORMAX) +#define C2F(Z) (qMAX*(Z)) + +#ifdef CCUT_METHOD_FLOAT #define CCUT(Z) ((COLORTYPE)(qMAX*Z)) #else /* CCUT_METHOD_INT */ #define CCUT(Z) ((COLORTYPE)((Z)/COLORMAX)) @@ -899,8 +891,6 @@ static void image_layer_cast(INT32 args) #else #ifdef COMBINE_METHOD_FLOAT -#define C2F(Z) (qMAX*(Z)) - #define COMBINE_ALPHA(S,L,aS,aL) \ ( (COLORTYPE)( ( (S)*(1.0-C2F(aL))*C2F(aS) + (L)*C2F(aL) ) / \ ( (C2F(aL)+(1-C2F(aL))*C2F(aS))) ) ) @@ -923,6 +913,8 @@ static void image_layer_cast(INT32 args) #define COMBINE_A(P,A) ((COLORTYPE)((P)*(A))) #define COMBINE_V(P,V,A) CCUT((V)*(P)*(A)) +#define CRAISE(Z) ((COLORTYPE)(COLORMAX*(Z))) + /*** layer mode definitions ***************************/ static void lm_normal(rgb_group *s,rgb_group *l,rgb_group *d, @@ -1032,144 +1024,71 @@ static void lm_normal(rgb_group *s,rgb_group *l,rgb_group *d, } } - -static void lm_add(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha) -{ - if (alpha==0.0) - { - MEMCPY(s,d,sizeof(rgb_group)*len); - MEMCPY(sa,da,sizeof(rgb_group)*len); - return; - } - else if (alpha==1.0) - { - if (!la) /* no layer alpha => full opaque */ - while (len--) - { - d->r=MINIMUM(COLORMAX,COMBINE(s->r,sa->r)+(int)l->r); - d->g=MINIMUM(COLORMAX,COMBINE(s->r,sa->g)+(int)l->g); - d->b=MINIMUM(COLORMAX,COMBINE(s->r,sa->b)+(int)l->b); - *da=white; - l++; s++; sa++; da++; d++; - } - else - while (len--) - { - d->r=MINIMUM(COLORMAX,COMBINE(s->r,sa->r)+ - (int)COMBINE(l->r,la->r)); - d->g=MINIMUM(COLORMAX,COMBINE(s->g,sa->g)+ - (int)COMBINE(l->g,la->g)); - d->b=MINIMUM(COLORMAX,COMBINE(s->b,sa->b)+ - (int)COMBINE(l->b,la->b)); - da->r=COMBINE_ALPHA_SUM(la->r,sa->r); - da->g=COMBINE_ALPHA_SUM(la->g,sa->g); - da->b=COMBINE_ALPHA_SUM(la->b,sa->b); - l++; s++; la++; sa++; da++; d++; - } - } - else - { - if (!la) /* no layer alpha => full opaque */ - while (len--) - { - d->r=MINIMUM(COLORMAX,COMBINE(s->r,sa->r)+ - (int)COMBINE_A(l->r,alpha)); - d->g=MINIMUM(COLORMAX,COMBINE(s->g,sa->g)+ - (int)COMBINE_A(l->g,alpha)); - d->b=MINIMUM(COLORMAX,COMBINE(s->b,sa->b)+ - (int)COMBINE_A(l->b,alpha)); - da->r=COMBINE_ALPHA_SUM_V(COLORMAX,sa->r,alpha); - da->g=COMBINE_ALPHA_SUM_V(COLORMAX,sa->g,alpha); - da->b=COMBINE_ALPHA_SUM_V(COLORMAX,sa->b,alpha); - l++; s++; sa++; da++; d++; - } - else - while (len--) - { - d->r=MINIMUM(COLORMAX, - COMBINE(s->r,sa->r)+(int)COMBINE_V(l->r,la->r,alpha)); - d->g=MINIMUM(COLORMAX, - COMBINE(s->g,sa->g)+(int)COMBINE_V(l->g,la->g,alpha)); - d->b=MINIMUM(COLORMAX, - COMBINE(s->b,sa->b)+(int)COMBINE_V(l->b,la->b,alpha)); - da->r=COMBINE_ALPHA_SUM_V(la->r,sa->r,alpha); - da->g=COMBINE_ALPHA_SUM_V(la->g,sa->g,alpha); - da->b=COMBINE_ALPHA_SUM_V(la->b,sa->b,alpha); - l++; s++; la++; sa++; da++; d++; - } - } -} - -static void lm_subtract(rgb_group *s,rgb_group *l,rgb_group *d, - rgb_group *sa,rgb_group *la,rgb_group *da, - int len,float alpha) -{ - if (alpha==0.0) - { - MEMCPY(s,d,sizeof(rgb_group)*len); - MEMCPY(sa,da,sizeof(rgb_group)*len); - return; - } - else if (alpha==1.0) - { - if (!la) /* no layer alpha => full opaque */ - while (len--) - { - d->r=MAXIMUM(0,COMBINE(s->r,sa->r)-(int)l->r); - d->g=MAXIMUM(0,COMBINE(s->r,sa->g)-(int)l->g); - d->b=MAXIMUM(0,COMBINE(s->r,sa->b)-(int)l->b); - *da=white; - l++; s++; sa++; da++; d++; - } - else - while (len--) - { - d->r=MAXIMUM(0,COMBINE(s->r,sa->r)- - (int)COMBINE(l->r,la->r)); - d->g=MAXIMUM(0,COMBINE(s->g,sa->g)- - (int)COMBINE(l->g,la->g)); - d->b=MAXIMUM(0,COMBINE(s->b,sa->b)- - (int)COMBINE(l->b,la->b)); - da->r=COMBINE_ALPHA_SUM(la->r,sa->r); - da->g=COMBINE_ALPHA_SUM(la->g,sa->g); - da->b=COMBINE_ALPHA_SUM(la->b,sa->b); - l++; s++; la++; sa++; da++; d++; - } - } - else - { - if (!la) /* no layer alpha => full opaque */ - while (len--) - { - d->r=MAXIMUM(0,COMBINE(s->r,sa->r)- - (int)COMBINE_A(l->r,alpha)); - d->g=MAXIMUM(0,COMBINE(s->g,sa->g)- - (int)COMBINE_A(l->g,alpha)); - d->b=MAXIMUM(0,COMBINE(s->b,sa->b)- - (int)COMBINE_A(l->b,alpha)); - da->r=COMBINE_ALPHA_SUM_V(COLORMAX,sa->r,alpha); - da->g=COMBINE_ALPHA_SUM_V(COLORMAX,sa->g,alpha); - da->b=COMBINE_ALPHA_SUM_V(COLORMAX,sa->b,alpha); - l++; s++; sa++; da++; d++; - } - else - while (len--) - { - d->r=MAXIMUM(0,COMBINE(s->r,sa->r)- - (int)COMBINE_V(l->r,la->r,alpha)); - d->g=MAXIMUM(0,COMBINE(s->g,sa->g)- - (int)COMBINE_V(l->g,la->g,alpha)); - d->b=MAXIMUM(0,COMBINE(s->b,sa->b)- - (int)COMBINE_V(l->b,la->b,alpha)); - da->r=COMBINE_ALPHA_SUM_V(la->r,sa->r,alpha); - da->g=COMBINE_ALPHA_SUM_V(la->g,sa->g,alpha); - da->b=COMBINE_ALPHA_SUM_V(la->b,sa->b,alpha); - l++; s++; la++; sa++; da++; d++; - } - } -} +/* operators from template */ + +#define LM_FUNC lm_add +#define L_TRUNC(X) MINIMUM(255,(X)) +#define L_OPER(A,B) ((A)+(int)(B)) +#include "layer_oper.h" +#undef LM_FUNC +#undef L_TRUNC +#undef L_OPER + +#define LM_FUNC lm_subtract +#define L_TRUNC(X) MAXIMUM(0,(X)) +#define L_OPER(A,B) ((A)-(int)(B)) +#include "layer_oper.h" +#undef LM_FUNC +#undef L_TRUNC +#undef L_OPER + +#define LM_FUNC lm_invsubtract +#define L_TRUNC(X) MAXIMUM(0,(X)) +#define L_OPER(A,B) ((B)-(int)(A)) +#include "layer_oper.h" +#undef LM_FUNC +#undef L_TRUNC +#undef L_OPER + +#define LM_FUNC lm_multiply +#define L_TRUNC(X) (X) +#define L_OPER(A,B) CCUT((A)*(int)(B)) +#include "layer_oper.h" +#undef LM_FUNC +#undef L_TRUNC +#undef L_OPER + +#define LM_FUNC lm_divide +#define L_TRUNC(X) MINIMUM(255,(X)) +#define L_OPER(A,B) ((A)/C2F(1+(int)(B))) +#include "layer_oper.h" +#undef LM_FUNC +#undef L_TRUNC +#undef L_OPER + +#define LM_FUNC lm_modulo +#define L_TRUNC(X) ((COLORTYPE)(X)) +#define L_OPER(A,B) ((A)%((B)?(B):1)) +#include "layer_oper.h" +#undef LM_FUNC +#undef L_TRUNC +#undef L_OPER + +#define LM_FUNC lm_invdivide +#define L_TRUNC(X) MINIMUM(255,(X)) +#define L_OPER(A,B) ((B)/C2F(1+(int)(A))) +#include "layer_oper.h" +#undef LM_FUNC +#undef L_TRUNC +#undef L_OPER + +#define LM_FUNC lm_invmodulo +#define L_TRUNC(X) ((COLORTYPE)(X)) +#define L_OPER(A,B) ((B)%(A)) +#include "layer_oper.h" +#undef LM_FUNC +#undef L_TRUNC +#undef L_OPER static void lm_dissolve(rgb_group *s,rgb_group *l,rgb_group *d, rgb_group *sa,rgb_group *la,rgb_group *da,