- Added option 'convert to premul' to AlphaOver node in Compositor

- Fixed mix mode "Overlay", it was missing a multiplication with 2 :)
- small bugix in Matts nodes commit, wrong pointers transfered to coltobw()
This commit is contained in:
Ton Roosendaal 2006-02-17 15:44:46 +00:00
parent 90fa460d2a
commit 6f62023850
3 changed files with 61 additions and 26 deletions

@ -831,18 +831,18 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
break;
case MA_RAMP_OVERLAY:
if(*r < 0.5f)
*r *= (facm + fac*col[0]);
*r *= (facm + 2.0f*fac*col[0]);
else
*r = 1.0 - (facm + fac*(1.0 - col[0])) * (1.0 - *r);
*r = 1.0 - (facm + 2.0f*fac*(1.0 - col[0])) * (1.0 - *r);
if(g) {
if(*g < 0.5f)
*g *= (facm + fac*col[1]);
*g *= (facm + 2.0f*fac*col[1]);
else
*g = 1.0 - (facm + fac*(1.0 - col[1])) * (1.0 - *g);
*g = 1.0 - (facm + 2.0f*fac*(1.0 - col[1])) * (1.0 - *g);
if(*b < 0.5f)
*b *= (facm + fac*col[2]);
*b *= (facm + 2.0f*fac*col[2]);
else
*b = 1.0 - (facm + fac*(1.0 - col[2])) * (1.0 - *b);
*b = 1.0 - (facm + 2.0f*fac*(1.0 - col[2])) * (1.0 - *b);
}
break;
case MA_RAMP_SUB:

@ -448,21 +448,6 @@ static void composit3_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_b
}
}
/* ok to delete this and use the generalised version below? */
static CompBuf *alphabuf_from_rgbabuf(CompBuf *cbuf)
{
CompBuf *valbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
float *valf, *rectf;
int tot;
valf= valbuf->rect;
rectf= cbuf->rect + 3;
for(tot= cbuf->x*cbuf->y; tot>0; tot--, valf++, rectf+=4)
*valf= *rectf;
return valbuf;
}
static CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel)
{
CompBuf *valbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
@ -1571,7 +1556,7 @@ static void node_composit_exec_rgbtobw(void *data, bNode *node, bNodeStack **in,
/* input no image? then only color operation */
if(in[0]->data==NULL) {
do_rgbtobw(node, out[0], in[0]);
do_rgbtobw(node, out[0]->vec, in[0]->vec);
}
else {
/* make output size of input image */
@ -1789,7 +1774,7 @@ static bNodeSocketType cmp_node_alphaover_out[]= {
{ -1, 0, "" }
};
static void do_alphaover(bNode *node, float *out, float *src, float *over)
static void do_alphaover_premul(bNode *node, float *out, float *src, float *over)
{
if(over[3]<=0.0f) {
@ -1817,6 +1802,37 @@ static void do_alphaover(bNode *node, float *out, float *src, float *over)
}
}
/* result will be still premul, but the over part is premulled */
static void do_alphaover_key(bNode *node, float *out, float *src, float *over)
{
if(over[3]<=0.0f) {
QUATCOPY(out, src);
}
else if(over[3]>=1.0f) {
QUATCOPY(out, over);
}
else {
float premul= over[3];
float mul= 1.0f - premul;
/* handle case where backdrop has no alpha, but still color */
if(src[0]==0.0f) {
out[0]= over[0];
out[1]= (mul*src[1]) + premul*over[1];
out[2]= (mul*src[2]) + premul*over[2];
out[3]= (mul*src[3]) + premul*over[3];
}
else {
out[0]= (mul*src[0]) + premul*over[0];
out[1]= (mul*src[1]) + premul*over[1];
out[2]= (mul*src[2]) + premul*over[2];
out[3]= (mul*src[3]) + premul*over[3];
}
}
}
static void node_composit_exec_alphaover(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
/* stack order in: col col */
@ -1824,24 +1840,28 @@ static void node_composit_exec_alphaover(void *data, bNode *node, bNodeStack **i
/* input no image? then only color operation */
if(in[0]->data==NULL) {
do_alphaover(node, out[0]->vec, in[0]->vec, in[1]->vec);
do_alphaover_premul(node, out[0]->vec, in[0]->vec, in[1]->vec);
}
else {
/* make output size of input image */
CompBuf *cbuf= in[0]->data;
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs
composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_alphaover);
if(node->custom1)
composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_alphaover_key);
else
composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_alphaover_premul);
out[0]->data= stackbuf;
}
}
/* custom1: convert 'over' to premul */
static bNodeType cmp_node_alphaover= {
/* type code */ CMP_NODE_ALPHAOVER,
/* name */ "AlphaOver",
/* width+range */ 80, 40, 120,
/* class+opts */ NODE_CLASS_OPERATOR, 0,
/* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS,
/* input sock */ cmp_node_alphaover_in,
/* output sock */ cmp_node_alphaover_out,
/* storage */ "",

@ -885,6 +885,18 @@ static int node_composit_buts_time(uiBlock *block, bNodeTree *ntree, bNode *node
return node->width-NODE_DY;
}
static int node_composit_buts_alphaover(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
/* alpha type */
uiDefButS(block, TOG, B_NODE_EXEC+node->nr, "ConvertPremul",
butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19,
&node->custom1, 0, 0, 0, 0, "");
}
return 19;
}
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
@ -935,6 +947,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_TIME:
ntype->butfunc= node_composit_buts_time;
break;
case CMP_NODE_ALPHAOVER:
ntype->butfunc= node_composit_buts_alphaover;
break;
default:
ntype->butfunc= NULL;
}