diff -Naur blender2.42/source/blender/blenkernel/BKE_node.h blender-work/source/blender/blenkernel/BKE_node.h --- blender2.42/source/blender/blenkernel/BKE_node.h 2006-07-03 05:49:12.000000000 -0400 +++ blender-work/source/blender/blenkernel/BKE_node.h 2006-07-18 23:59:07.000000000 -0400 @@ -88,6 +88,7 @@ #define NODE_CLASS_GROUP 6 #define NODE_CLASS_FILE 7 #define NODE_CLASS_CONVERTOR 8 +#define NODE_CLASS_MATTE 9 /* ************** GENERIC API, TREES *************** */ @@ -220,10 +221,19 @@ #define CMP_NODE_IMAGE 220 #define CMP_NODE_R_LAYERS 221 #define CMP_NODE_COMPOSITE 222 -#define CMP_NODE_OUTPUT_FILE 223 +#define CMP_NODE_OUTPUT_FILE 223 #define CMP_NODE_TEXTURE 224 #define CMP_NODE_TRANSLATE 225 #define CMP_NODE_ZCOMBINE 226 +#define CMP_NODE_SEPYCCA 227 +#define CMP_NODE_SEPYUVA 228 +#define CMP_NODE_YUV_MATTE 229 +#define CMP_NODE_DIFF_MATTE 230 +#define CMP_NODE_CHROMA_MATTE 231 +#define CMP_NODE_COLOR_SPILL 232 +#define CMP_NODE_COMBRGBA 233 +#define CMP_NODE_DILATE_ERODE 234 + /* filter types */ diff -Naur blender2.42/source/blender/blenkernel/intern/node.c blender-work/source/blender/blenkernel/intern/node.c --- blender2.42/source/blender/blenkernel/intern/node.c 2006-07-09 07:54:41.000000000 -0400 +++ blender-work/source/blender/blenkernel/intern/node.c 2006-07-18 23:49:14.000000000 -0400 @@ -795,7 +795,36 @@ node->storage= nhs; nhs->hue= 0.5f; nhs->sat= 1.0f; + nhs->val= 1.0f; } + else if(type==CMP_NODE_YUV_MATTE){ + NodeChroma *c=MEM_callocN(sizeof(NodeChroma), "node chroma"); + node->storage=c; + c->rt=0.01f; + c->bt=0.01f; + c->gt=0.01f; + } + else if(type==CMP_NODE_DIFF_MATTE){ + NodeChroma *c=MEM_callocN(sizeof(NodeChroma), "node chroma"); + node->storage=c; + c->rt=0.01f; + c->bt=0.01f; + c->gt=0.01f; + } + else if(type==CMP_NODE_CHROMA_MATTE){ + NodeChroma *c=MEM_callocN(sizeof(NodeChroma), "node chroma"); + node->storage=c; + c->rt=0.00f; + c->bt=0.00f; + c->gt=0.00f; + } + else if(type==CMP_NODE_COLOR_SPILL){ + NodeChroma *c=MEM_callocN(sizeof(NodeChroma), "node chroma"); + node->storage=c; + c->rt=0.00f; + c->bt=0.00f; + c->gt=0.00f; + } } return node; diff -Naur blender2.42/source/blender/blenkernel/intern/node_composite.c blender-work/source/blender/blenkernel/intern/node_composite.c --- blender2.42/source/blender/blenkernel/intern/node_composite.c 2006-07-03 11:25:11.000000000 -0400 +++ blender-work/source/blender/blenkernel/intern/node_composite.c 2006-07-19 13:45:31.000000000 -0400 @@ -1,31 +1,31 @@ /** - * $Id: node_composite.c,v 1.51 2006/07/03 15:25:11 ton Exp $ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2006 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ +* $Id: node_composite.c,v 1.51 2006/07/03 15:25:11 ton Exp $ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) 2006 Blender Foundation. +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL LICENSE BLOCK ***** +*/ #include #include @@ -63,14 +63,14 @@ /* general signal that's in output sockets, and goes over the wires */ typedef struct CompBuf { - float *rect; - int x, y, xrad, yrad; - short type, malloc; - rcti disprect; /* cropped part of image */ - int xof, yof; /* relative to center of target image */ - - void (*rect_procedural)(struct CompBuf *, float *, float, float); - bNode *node; + float *rect; + int x, y, xrad, yrad; + short type, malloc; + rcti disprect; /* cropped part of image */ + int xof, yof; /* relative to center of target image */ + + void (*rect_procedural)(struct CompBuf *, float *, float, float); + bNode *node; } CompBuf; /* defines also used for pixel size */ @@ -88,384 +88,384 @@ static CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc) { - CompBuf *cbuf= MEM_callocT(sizeof(CompBuf), "compbuf"); - - cbuf->x= sizex; - cbuf->y= sizey; - cbuf->xrad= sizex/2; - cbuf->yrad= sizey/2; - - cbuf->type= type; - if(alloc) { - if(cbuf->type==CB_RGBA) - cbuf->rect= MEM_mapallocT(4*sizeof(float)*sizex*sizey, "compbuf RGBA rect"); - else if(cbuf->type==CB_VEC3) - cbuf->rect= MEM_mapallocT(3*sizeof(float)*sizex*sizey, "compbuf Vector3 rect"); - else if(cbuf->type==CB_VEC2) - cbuf->rect= MEM_mapallocT(2*sizeof(float)*sizex*sizey, "compbuf Vector2 rect"); - else - cbuf->rect= MEM_mapallocT(sizeof(float)*sizex*sizey, "compbuf Fac rect"); - cbuf->malloc= 1; - } - cbuf->disprect.xmin= 0; - cbuf->disprect.ymin= 0; - cbuf->disprect.xmax= sizex; - cbuf->disprect.ymax= sizey; - - return cbuf; + CompBuf *cbuf= MEM_callocT(sizeof(CompBuf), "compbuf"); + + cbuf->x= sizex; + cbuf->y= sizey; + cbuf->xrad= sizex/2; + cbuf->yrad= sizey/2; + + cbuf->type= type; + if(alloc) { + if(cbuf->type==CB_RGBA) + cbuf->rect= MEM_mapallocT(4*sizeof(float)*sizex*sizey, "compbuf RGBA rect"); + else if(cbuf->type==CB_VEC3) + cbuf->rect= MEM_mapallocT(3*sizeof(float)*sizex*sizey, "compbuf Vector3 rect"); + else if(cbuf->type==CB_VEC2) + cbuf->rect= MEM_mapallocT(2*sizeof(float)*sizex*sizey, "compbuf Vector2 rect"); + else + cbuf->rect= MEM_mapallocT(sizeof(float)*sizex*sizey, "compbuf Fac rect"); + cbuf->malloc= 1; + } + cbuf->disprect.xmin= 0; + cbuf->disprect.ymin= 0; + cbuf->disprect.xmax= sizex; + cbuf->disprect.ymax= sizey; + + return cbuf; } static CompBuf *dupalloc_compbuf(CompBuf *cbuf) { - CompBuf *dupbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1); - if(dupbuf) - memcpy(dupbuf->rect, cbuf->rect, cbuf->type*sizeof(float)*cbuf->x*cbuf->y); - return dupbuf; + CompBuf *dupbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1); + if(dupbuf) + memcpy(dupbuf->rect, cbuf->rect, cbuf->type*sizeof(float)*cbuf->x*cbuf->y); + return dupbuf; } static CompBuf *pass_on_compbuf(CompBuf *cbuf) { - CompBuf *dupbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 0); - dupbuf->rect= cbuf->rect; - - /* this is hacky solution to make sure outputs get the real compbuf (so freeing goes OK) */ - if(cbuf->malloc) { - cbuf->malloc= 0; - dupbuf->malloc= 1; - } - - return dupbuf; + CompBuf *dupbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 0); + dupbuf->rect= cbuf->rect; + + /* this is hacky solution to make sure outputs get the real compbuf (so freeing goes OK) */ + if(cbuf->malloc) { + cbuf->malloc= 0; + dupbuf->malloc= 1; + } + + return dupbuf; } void free_compbuf(CompBuf *cbuf) { - if(cbuf->malloc && cbuf->rect) - MEM_freeT(cbuf->rect); + if(cbuf->malloc && cbuf->rect) + MEM_freeT(cbuf->rect); - MEM_freeT(cbuf); + MEM_freeT(cbuf); } void print_compbuf(char *str, CompBuf *cbuf) { - printf("Compbuf %s %d %d %p\n", str, cbuf->x, cbuf->y, cbuf->rect); - + printf("Compbuf %s %d %d %p\n", str, cbuf->x, cbuf->y, cbuf->rect); + } static CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type) { - CompBuf *cbuf; - rcti disprect= *drect; - float *outfp; - int dx, y; - - if(disprect.xmax>rectx) disprect.xmax= rectx; - if(disprect.ymax>recty) disprect.ymax= recty; - if(disprect.xmin>= disprect.xmax) return NULL; - if(disprect.ymin>= disprect.ymax) return NULL; - - cbuf= alloc_compbuf(disprect.xmax-disprect.xmin, disprect.ymax-disprect.ymin, type, 1); - outfp= cbuf->rect; - rectf += type*(disprect.ymin*rectx + disprect.xmin); - dx= type*cbuf->x; - for(y=cbuf->y; y>0; y--, outfp+=dx, rectf+=type*rectx) - memcpy(outfp, rectf, sizeof(float)*dx); - - return cbuf; + CompBuf *cbuf; + rcti disprect= *drect; + float *outfp; + int dx, y; + + if(disprect.xmax>rectx) disprect.xmax= rectx; + if(disprect.ymax>recty) disprect.ymax= recty; + if(disprect.xmin>= disprect.xmax) return NULL; + if(disprect.ymin>= disprect.ymax) return NULL; + + cbuf= alloc_compbuf(disprect.xmax-disprect.xmin, disprect.ymax-disprect.ymin, type, 1); + outfp= cbuf->rect; + rectf += type*(disprect.ymin*rectx + disprect.xmin); + dx= type*cbuf->x; + for(y=cbuf->y; y>0; y--, outfp+=dx, rectf+=type*rectx) + memcpy(outfp, rectf, sizeof(float)*dx); + + return cbuf; } static CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy) { - CompBuf *outbuf; - float *rectf, *newrectf, *rf; - int x, y, c, pixsize= inbuf->type; - int ofsx, ofsy, stepx, stepy; - - if(inbuf->x==newx && inbuf->y==newy) - return dupalloc_compbuf(inbuf); - - outbuf= alloc_compbuf(newx, newy, inbuf->type, 1); - newrectf= outbuf->rect; - - stepx = (65536.0 * (inbuf->x - 1.0) / (newx - 1.0)) + 0.5; - stepy = (65536.0 * (inbuf->y - 1.0) / (newy - 1.0)) + 0.5; - ofsy = 32768; - - for (y = newy; y > 0 ; y--){ - rectf = inbuf->rect; - rectf += pixsize * (ofsy >> 16) * inbuf->x; - - ofsy += stepy; - ofsx = 32768; - - for (x = newx ; x>0 ; x--) { - - rf= rectf + pixsize*(ofsx >> 16); - for(c=0; ctype; + int ofsx, ofsy, stepx, stepy; + + if(inbuf->x==newx && inbuf->y==newy) + return dupalloc_compbuf(inbuf); + + outbuf= alloc_compbuf(newx, newy, inbuf->type, 1); + newrectf= outbuf->rect; + + stepx = (65536.0 * (inbuf->x - 1.0) / (newx - 1.0)) + 0.5; + stepy = (65536.0 * (inbuf->y - 1.0) / (newy - 1.0)) + 0.5; + ofsy = 32768; + + for (y = newy; y > 0 ; y--){ + rectf = inbuf->rect; + rectf += pixsize * (ofsy >> 16) * inbuf->x; + + ofsy += stepy; + ofsx = 32768; + + for (x = newx ; x>0 ; x--) { + + rf= rectf + pixsize*(ofsx >> 16); + for(c=0; ctype!=type && inbuf->rect_procedural==NULL) { - CompBuf *outbuf= alloc_compbuf(inbuf->x, inbuf->y, type, 1); - float *inrf= inbuf->rect; - float *outrf= outbuf->rect; - int x= inbuf->x*inbuf->y; - - if(type==CB_VAL && inbuf->type==CB_VEC3) { - for(; x>0; x--, outrf+= 1, inrf+= 3) - *outrf= 0.333333f*(inrf[0]+inrf[1]+inrf[2]); - } - else if(type==CB_VAL && inbuf->type==CB_RGBA) { - for(; x>0; x--, outrf+= 1, inrf+= 4) - *outrf= inrf[0]*0.35f + inrf[1]*0.45f + inrf[2]*0.2f; - } - else if(type==CB_VEC3 && inbuf->type==CB_VAL) { - for(; x>0; x--, outrf+= 3, inrf+= 1) { - outrf[0]= inrf[0]; - outrf[1]= inrf[0]; - outrf[2]= inrf[0]; - } - } - else if(type==CB_VEC3 && inbuf->type==CB_RGBA) { - for(; x>0; x--, outrf+= 3, inrf+= 4) { - outrf[0]= inrf[0]; - outrf[1]= inrf[1]; - outrf[2]= inrf[2]; - } - } - else if(type==CB_RGBA && inbuf->type==CB_VAL) { - for(; x>0; x--, outrf+= 4, inrf+= 1) { - outrf[0]= inrf[0]; - outrf[1]= inrf[0]; - outrf[2]= inrf[0]; - outrf[3]= inrf[0]; - } - } - else if(type==CB_RGBA && inbuf->type==CB_VEC3) { - for(; x>0; x--, outrf+= 4, inrf+= 3) { - outrf[0]= inrf[0]; - outrf[1]= inrf[1]; - outrf[2]= inrf[2]; - outrf[3]= 1.0f; - } - } - - return outbuf; - } - return inbuf; + if(inbuf && inbuf->type!=type && inbuf->rect_procedural==NULL) { + CompBuf *outbuf= alloc_compbuf(inbuf->x, inbuf->y, type, 1); + float *inrf= inbuf->rect; + float *outrf= outbuf->rect; + int x= inbuf->x*inbuf->y; + + if(type==CB_VAL && inbuf->type==CB_VEC3) { + for(; x>0; x--, outrf+= 1, inrf+= 3) + *outrf= 0.333333f*(inrf[0]+inrf[1]+inrf[2]); + } + else if(type==CB_VAL && inbuf->type==CB_RGBA) { + for(; x>0; x--, outrf+= 1, inrf+= 4) + *outrf= inrf[0]*0.35f + inrf[1]*0.45f + inrf[2]*0.2f; + } + else if(type==CB_VEC3 && inbuf->type==CB_VAL) { + for(; x>0; x--, outrf+= 3, inrf+= 1) { + outrf[0]= inrf[0]; + outrf[1]= inrf[0]; + outrf[2]= inrf[0]; + } + } + else if(type==CB_VEC3 && inbuf->type==CB_RGBA) { + for(; x>0; x--, outrf+= 3, inrf+= 4) { + outrf[0]= inrf[0]; + outrf[1]= inrf[1]; + outrf[2]= inrf[2]; + } + } + else if(type==CB_RGBA && inbuf->type==CB_VAL) { + for(; x>0; x--, outrf+= 4, inrf+= 1) { + outrf[0]= inrf[0]; + outrf[1]= inrf[0]; + outrf[2]= inrf[0]; + outrf[3]= inrf[0]; + } + } + else if(type==CB_RGBA && inbuf->type==CB_VEC3) { + for(; x>0; x--, outrf+= 4, inrf+= 3) { + outrf[0]= inrf[0]; + outrf[1]= inrf[1]; + outrf[2]= inrf[2]; + outrf[3]= 1.0f; + } + } + + return outbuf; + } + return inbuf; } float *compbuf_get_pixel(CompBuf *cbuf, float *rectf, int x, int y, int xrad, int yrad) { - if(cbuf) { - if(cbuf->rect_procedural) { - cbuf->rect_procedural(cbuf, rectf, (float)x/(float)xrad, (float)y/(float)yrad); - return rectf; - } - else { - static float col[4]= {0.0f, 0.0f, 0.0f, 0.0f}; - - /* map coords */ - x-= cbuf->xof; - y-= cbuf->yof; - - if(y<-cbuf->yrad || y>= -cbuf->yrad+cbuf->y) return col; - if(x<-cbuf->xrad || x>= -cbuf->xrad+cbuf->x) return col; - - return cbuf->rect + cbuf->type*( (cbuf->yrad+y)*cbuf->x + (cbuf->xrad+x) ); - } - } - else return rectf; + if(cbuf) { + if(cbuf->rect_procedural) { + cbuf->rect_procedural(cbuf, rectf, (float)x/(float)xrad, (float)y/(float)yrad); + return rectf; + } + else { + static float col[4]= {0.0f, 0.0f, 0.0f, 0.0f}; + + /* map coords */ + x-= cbuf->xof; + y-= cbuf->yof; + + if(y<-cbuf->yrad || y>= -cbuf->yrad+cbuf->y) return col; + if(x<-cbuf->xrad || x>= -cbuf->xrad+cbuf->x) return col; + + return cbuf->rect + cbuf->type*( (cbuf->yrad+y)*cbuf->x + (cbuf->xrad+x) ); + } + } + else return rectf; } /* **************************************************** */ /* Pixel-to-Pixel operation, 1 Image in, 1 out */ static void composit1_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, float *src_col, - void (*func)(bNode *, float *, float *), - int src_type) + void (*func)(bNode *, float *, float *), + int src_type) { - CompBuf *src_use; - float *outfp=out->rect, *srcfp; - int xrad, yrad, x, y; - - src_use= typecheck_compbuf(src_buf, src_type); - - xrad= out->xrad; - yrad= out->yrad; - - for(y= -yrad; y<-yrad+out->y; y++) { - for(x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) { - srcfp= compbuf_get_pixel(src_use, src_col, x, y, xrad, yrad); - func(node, outfp, srcfp); - } - } - - if(src_use!=src_buf) - free_compbuf(src_use); + CompBuf *src_use; + float *outfp=out->rect, *srcfp; + int xrad, yrad, x, y; + + src_use= typecheck_compbuf(src_buf, src_type); + + xrad= out->xrad; + yrad= out->yrad; + + for(y= -yrad; y<-yrad+out->y; y++) { + for(x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) { + srcfp= compbuf_get_pixel(src_use, src_col, x, y, xrad, yrad); + func(node, outfp, srcfp); + } + } + + if(src_use!=src_buf) + free_compbuf(src_use); } /* Pixel-to-Pixel operation, 2 Images in, 1 out */ static void composit2_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, float *src_col, - CompBuf *fac_buf, float *fac, void (*func)(bNode *, float *, float *, float *), - int src_type, int fac_type) + CompBuf *fac_buf, float *fac, void (*func)(bNode *, float *, float *, float *), + int src_type, int fac_type) { - CompBuf *src_use, *fac_use; - float *outfp=out->rect, *srcfp, *facfp; - int xrad, yrad, x, y; - - src_use= typecheck_compbuf(src_buf, src_type); - fac_use= typecheck_compbuf(fac_buf, fac_type); - - xrad= out->xrad; - yrad= out->yrad; - - for(y= -yrad; y<-yrad+out->y; y++) { - for(x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) { - srcfp= compbuf_get_pixel(src_use, src_col, x, y, xrad, yrad); - facfp= compbuf_get_pixel(fac_use, fac, x, y, xrad, yrad); - - func(node, outfp, srcfp, facfp); - } - } - if(src_use!=src_buf) - free_compbuf(src_use); - if(fac_use!=fac_buf) - free_compbuf(fac_use); + CompBuf *src_use, *fac_use; + float *outfp=out->rect, *srcfp, *facfp; + int xrad, yrad, x, y; + + src_use= typecheck_compbuf(src_buf, src_type); + fac_use= typecheck_compbuf(fac_buf, fac_type); + + xrad= out->xrad; + yrad= out->yrad; + + for(y= -yrad; y<-yrad+out->y; y++) { + for(x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) { + srcfp= compbuf_get_pixel(src_use, src_col, x, y, xrad, yrad); + facfp= compbuf_get_pixel(fac_use, fac, x, y, xrad, yrad); + + func(node, outfp, srcfp, facfp); + } + } + if(src_use!=src_buf) + free_compbuf(src_use); + if(fac_use!=fac_buf) + free_compbuf(fac_use); } /* Pixel-to-Pixel operation, 3 Images in, 1 out */ static void composit3_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, float *src1_col, CompBuf *src2_buf, float *src2_col, - CompBuf *fac_buf, float *fac, void (*func)(bNode *, float *, float *, float *, float *), - int src1_type, int src2_type, int fac_type) + CompBuf *fac_buf, float *fac, void (*func)(bNode *, float *, float *, float *, float *), + int src1_type, int src2_type, int fac_type) { - CompBuf *src1_use, *src2_use, *fac_use; - float *outfp=out->rect, *src1fp, *src2fp, *facfp; - int xrad, yrad, x, y; - - src1_use= typecheck_compbuf(src1_buf, src1_type); - src2_use= typecheck_compbuf(src2_buf, src2_type); - fac_use= typecheck_compbuf(fac_buf, fac_type); - - xrad= out->xrad; - yrad= out->yrad; - - for(y= -yrad; y<-yrad+out->y; y++) { - for(x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) { - src1fp= compbuf_get_pixel(src1_use, src1_col, x, y, xrad, yrad); - src2fp= compbuf_get_pixel(src2_use, src2_col, x, y, xrad, yrad); - facfp= compbuf_get_pixel(fac_use, fac, x, y, xrad, yrad); - - func(node, outfp, src1fp, src2fp, facfp); - } - } - - if(src1_use!=src1_buf) - free_compbuf(src1_use); - if(src2_use!=src2_buf) - free_compbuf(src2_use); - if(fac_use!=fac_buf) - free_compbuf(fac_use); + CompBuf *src1_use, *src2_use, *fac_use; + float *outfp=out->rect, *src1fp, *src2fp, *facfp; + int xrad, yrad, x, y; + + src1_use= typecheck_compbuf(src1_buf, src1_type); + src2_use= typecheck_compbuf(src2_buf, src2_type); + fac_use= typecheck_compbuf(fac_buf, fac_type); + + xrad= out->xrad; + yrad= out->yrad; + + for(y= -yrad; y<-yrad+out->y; y++) { + for(x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) { + src1fp= compbuf_get_pixel(src1_use, src1_col, x, y, xrad, yrad); + src2fp= compbuf_get_pixel(src2_use, src2_col, x, y, xrad, yrad); + facfp= compbuf_get_pixel(fac_use, fac, x, y, xrad, yrad); + + func(node, outfp, src1fp, src2fp, facfp); + } + } + + if(src1_use!=src1_buf) + free_compbuf(src1_use); + if(src2_use!=src2_buf) + free_compbuf(src2_use); + if(fac_use!=fac_buf) + free_compbuf(fac_use); } /* Pixel-to-Pixel operation, 4 Images in, 1 out */ static void composit4_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, float *src1_col, CompBuf *fac1_buf, float *fac1, - CompBuf *src2_buf, float *src2_col, CompBuf *fac2_buf, float *fac2, - void (*func)(bNode *, float *, float *, float *, float *, float *), - int src1_type, int fac1_type, int src2_type, int fac2_type) -{ - CompBuf *src1_use, *src2_use, *fac1_use, *fac2_use; - float *outfp=out->rect, *src1fp, *src2fp, *fac1fp, *fac2fp; - int xrad, yrad, x, y; - - src1_use= typecheck_compbuf(src1_buf, src1_type); - src2_use= typecheck_compbuf(src2_buf, src2_type); - fac1_use= typecheck_compbuf(fac1_buf, fac1_type); - fac2_use= typecheck_compbuf(fac2_buf, fac2_type); - - xrad= out->xrad; - yrad= out->yrad; - - for(y= -yrad; y<-yrad+out->y; y++) { - for(x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) { - src1fp= compbuf_get_pixel(src1_use, src1_col, x, y, xrad, yrad); - src2fp= compbuf_get_pixel(src2_use, src2_col, x, y, xrad, yrad); - fac1fp= compbuf_get_pixel(fac1_use, fac1, x, y, xrad, yrad); - fac2fp= compbuf_get_pixel(fac2_use, fac2, x, y, xrad, yrad); - - func(node, outfp, src1fp, fac1fp, src2fp, fac2fp); - } - } - - if(src1_use!=src1_buf) - free_compbuf(src1_use); - if(src2_use!=src2_buf) - free_compbuf(src2_use); - if(fac1_use!=fac1_buf) - free_compbuf(fac1_use); - if(fac2_use!=fac2_buf) - free_compbuf(fac2_use); + CompBuf *src2_buf, float *src2_col, CompBuf *fac2_buf, float *fac2, + void (*func)(bNode *, float *, float *, float *, float *, float *), + int src1_type, int fac1_type, int src2_type, int fac2_type) +{ + CompBuf *src1_use, *src2_use, *fac1_use, *fac2_use; + float *outfp=out->rect, *src1fp, *src2fp, *fac1fp, *fac2fp; + int xrad, yrad, x, y; + + src1_use= typecheck_compbuf(src1_buf, src1_type); + src2_use= typecheck_compbuf(src2_buf, src2_type); + fac1_use= typecheck_compbuf(fac1_buf, fac1_type); + fac2_use= typecheck_compbuf(fac2_buf, fac2_type); + + xrad= out->xrad; + yrad= out->yrad; + + for(y= -yrad; y<-yrad+out->y; y++) { + for(x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) { + src1fp= compbuf_get_pixel(src1_use, src1_col, x, y, xrad, yrad); + src2fp= compbuf_get_pixel(src2_use, src2_col, x, y, xrad, yrad); + fac1fp= compbuf_get_pixel(fac1_use, fac1, x, y, xrad, yrad); + fac2fp= compbuf_get_pixel(fac2_use, fac2, x, y, xrad, yrad); + + func(node, outfp, src1fp, fac1fp, src2fp, fac2fp); + } + } + + if(src1_use!=src1_buf) + free_compbuf(src1_use); + if(src2_use!=src2_buf) + free_compbuf(src2_use); + if(fac1_use!=fac1_buf) + free_compbuf(fac1_use); + if(fac2_use!=fac2_buf) + free_compbuf(fac2_use); } static CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel) { - CompBuf *valbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); - float *valf, *rectf; - int tot; - - valf= valbuf->rect; - - /* defaults to returning alpha channel */ - if ((channel < CHAN_R) && (channel > CHAN_A)) channel = CHAN_A; - - rectf= cbuf->rect + channel; - - for(tot= cbuf->x*cbuf->y; tot>0; tot--, valf++, rectf+=4) - *valf= *rectf; - - return valbuf; + CompBuf *valbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); + float *valf, *rectf; + int tot; + + valf= valbuf->rect; + + /* defaults to returning alpha channel */ + if ((channel < CHAN_R) && (channel > CHAN_A)) channel = CHAN_A; + + rectf= cbuf->rect + channel; + + for(tot= cbuf->x*cbuf->y; tot>0; tot--, valf++, rectf+=4) + *valf= *rectf; + + return valbuf; } static void generate_preview(bNode *node, CompBuf *stackbuf) { - bNodePreview *preview= node->preview; - - if(preview && stackbuf) { - CompBuf *cbuf, *stackbuf_use; - - if(stackbuf->rect==NULL) return; - - stackbuf_use= typecheck_compbuf(stackbuf, CB_RGBA); - - if(stackbuf->x > stackbuf->y) { - preview->xsize= 140; - preview->ysize= (140*stackbuf->y)/stackbuf->x; - } - else { - preview->ysize= 140; - preview->xsize= (140*stackbuf->x)/stackbuf->y; - } - - cbuf= scalefast_compbuf(stackbuf_use, preview->xsize, preview->ysize); - - /* this ensures free-compbuf does the right stuff */ - SWAP(float *, cbuf->rect, node->preview->rect); - - free_compbuf(cbuf); - if(stackbuf_use!=stackbuf) - free_compbuf(stackbuf_use); + bNodePreview *preview= node->preview; + + if(preview && stackbuf) { + CompBuf *cbuf, *stackbuf_use; - } + if(stackbuf->rect==NULL) return; + + stackbuf_use= typecheck_compbuf(stackbuf, CB_RGBA); + + if(stackbuf->x > stackbuf->y) { + preview->xsize= 140; + preview->ysize= (140*stackbuf->y)/stackbuf->x; + } + else { + preview->ysize= 140; + preview->xsize= (140*stackbuf->x)/stackbuf->y; + } + + cbuf= scalefast_compbuf(stackbuf_use, preview->xsize, preview->ysize); + + /* this ensures free-compbuf does the right stuff */ + SWAP(float *, cbuf->rect, node->preview->rect); + + free_compbuf(cbuf); + if(stackbuf_use!=stackbuf) + free_compbuf(stackbuf_use); + + } } /* ******************************************************** */ @@ -473,436 +473,436 @@ /* ******************************************************** */ /* SocketType syntax: - socket type, max connections (0 is no limit), name, 4 values for default, 2 values for range */ +socket type, max connections (0 is no limit), name, 4 values for default, 2 values for range */ /* Verification rule: If name changes, a saved socket and its links will be removed! Type changes are OK */ /* **************** VIEWER ******************** */ static bNodeSocketType cmp_node_viewer_in[]= { - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void do_copy_rgba(bNode *node, float *out, float *in) { - QUATCOPY(out, in); + QUATCOPY(out, in); } static void do_copy_rgb(bNode *node, float *out, float *in) { - VECCOPY(out, in); - out[3]= 1.0f; + VECCOPY(out, in); + out[3]= 1.0f; } static void do_copy_value(bNode *node, float *out, float *in) { - out[0]= in[0]; + out[0]= in[0]; } static void do_copy_a_rgba(bNode *node, float *out, float *in, float *fac) { - VECCOPY(out, in); - out[3]= *fac; + VECCOPY(out, in); + out[3]= *fac; } static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* image assigned to output */ - /* stack order input sockets: col, alpha, z */ - - if(node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */ - Image *ima= (Image *)node->id; - CompBuf *cbuf, *tbuf; - int rectx, recty; - - tbuf= in[0]->data?in[0]->data:(in[1]->data?in[1]->data:in[2]->data); - if(tbuf==NULL) { - rectx= 320; recty= 256; - } - else { - rectx= tbuf->x; - recty= tbuf->y; - } - - /* full copy of imbuf, but threadsafe... */ - if(ima->ibuf==NULL) { - ima->ibuf = MEM_callocT(sizeof(struct ImBuf), "ImBuf_struct"); - ima->ibuf->depth= 32; - ima->ibuf->ftype= TGA; - } - - /* cleanup of composit image */ - if(ima->ibuf->rect) { - MEM_freeT(ima->ibuf->rect); - ima->ibuf->rect= NULL; - ima->ibuf->mall &= ~IB_rect; - } - if(ima->ibuf->zbuf_float) { - MEM_freeT(ima->ibuf->zbuf_float); - ima->ibuf->zbuf_float= NULL; - ima->ibuf->mall &= ~IB_zbuffloat; - } - if(ima->ibuf->rect_float) - MEM_freeT(ima->ibuf->rect_float); - - ima->ibuf->x= rectx; - ima->ibuf->y= recty; - ima->ibuf->mall |= IB_rectfloat; - ima->ibuf->rect_float= MEM_mallocT(4*rectx*recty*sizeof(float), "viewer rect"); - - /* now we combine the input with ibuf */ - cbuf= alloc_compbuf(rectx, recty, CB_RGBA, 0); // no alloc - cbuf->rect= ima->ibuf->rect_float; - - /* when no alpha, we can simply copy */ - if(in[1]->data==NULL) { - composit1_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, do_copy_rgba, CB_RGBA); - } - else - composit2_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL); - - if(in[2]->data) { - CompBuf *zbuf= alloc_compbuf(rectx, recty, CB_VAL, 1); - ima->ibuf->zbuf_float= zbuf->rect; - ima->ibuf->mall |= IB_zbuffloat; - - composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value, CB_VAL); - - /* free compbuf, but not the rect */ - zbuf->malloc= 0; - free_compbuf(zbuf); - } - - generate_preview(node, cbuf); - free_compbuf(cbuf); - - } /* lets make only previews when not done yet, so activating doesnt update */ - else if(in[0]->data && node->preview && node->preview->rect==NULL) { - CompBuf *cbuf, *inbuf= in[0]->data; - - if(inbuf->type!=CB_RGBA) { - cbuf= alloc_compbuf(inbuf->x, inbuf->y, CB_RGBA, 1); - composit1_pixel_processor(node, cbuf, inbuf, in[0]->vec, do_copy_rgba, CB_RGBA); - generate_preview(node, cbuf); - free_compbuf(cbuf); - } - else - generate_preview(node, inbuf); - } + /* image assigned to output */ + /* stack order input sockets: col, alpha, z */ + + if(node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */ + Image *ima= (Image *)node->id; + CompBuf *cbuf, *tbuf; + int rectx, recty; + + tbuf= in[0]->data?in[0]->data:(in[1]->data?in[1]->data:in[2]->data); + if(tbuf==NULL) { + rectx= 320; recty= 256; + } + else { + rectx= tbuf->x; + recty= tbuf->y; + } + + /* full copy of imbuf, but threadsafe... */ + if(ima->ibuf==NULL) { + ima->ibuf = MEM_callocT(sizeof(struct ImBuf), "ImBuf_struct"); + ima->ibuf->depth= 32; + ima->ibuf->ftype= TGA; + } + + /* cleanup of composit image */ + if(ima->ibuf->rect) { + MEM_freeT(ima->ibuf->rect); + ima->ibuf->rect= NULL; + ima->ibuf->mall &= ~IB_rect; + } + if(ima->ibuf->zbuf_float) { + MEM_freeT(ima->ibuf->zbuf_float); + ima->ibuf->zbuf_float= NULL; + ima->ibuf->mall &= ~IB_zbuffloat; + } + if(ima->ibuf->rect_float) + MEM_freeT(ima->ibuf->rect_float); + + ima->ibuf->x= rectx; + ima->ibuf->y= recty; + ima->ibuf->mall |= IB_rectfloat; + ima->ibuf->rect_float= MEM_mallocT(4*rectx*recty*sizeof(float), "viewer rect"); + + /* now we combine the input with ibuf */ + cbuf= alloc_compbuf(rectx, recty, CB_RGBA, 0); // no alloc + cbuf->rect= ima->ibuf->rect_float; + + /* when no alpha, we can simply copy */ + if(in[1]->data==NULL) { + composit1_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, do_copy_rgba, CB_RGBA); + } + else + composit2_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL); + + if(in[2]->data) { + CompBuf *zbuf= alloc_compbuf(rectx, recty, CB_VAL, 1); + ima->ibuf->zbuf_float= zbuf->rect; + ima->ibuf->mall |= IB_zbuffloat; + + composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value, CB_VAL); + + /* free compbuf, but not the rect */ + zbuf->malloc= 0; + free_compbuf(zbuf); + } + + generate_preview(node, cbuf); + free_compbuf(cbuf); + + } /* lets make only previews when not done yet, so activating doesnt update */ + else if(in[0]->data && node->preview && node->preview->rect==NULL) { + CompBuf *cbuf, *inbuf= in[0]->data; + + if(inbuf->type!=CB_RGBA) { + cbuf= alloc_compbuf(inbuf->x, inbuf->y, CB_RGBA, 1); + composit1_pixel_processor(node, cbuf, inbuf, in[0]->vec, do_copy_rgba, CB_RGBA); + generate_preview(node, cbuf); + free_compbuf(cbuf); + } + else + generate_preview(node, inbuf); + } } static bNodeType cmp_node_viewer= { - /* type code */ CMP_NODE_VIEWER, - /* name */ "Viewer", - /* width+range */ 80, 60, 200, - /* class+opts */ NODE_CLASS_OUTPUT, NODE_PREVIEW, - /* input sock */ cmp_node_viewer_in, - /* output sock */ NULL, - /* storage */ "", - /* execfunc */ node_composit_exec_viewer - + /* type code */ CMP_NODE_VIEWER, + /* name */ "Viewer", + /* width+range */ 80, 60, 200, + /* class+opts */ NODE_CLASS_OUTPUT, NODE_PREVIEW, + /* input sock */ cmp_node_viewer_in, + /* output sock */ NULL, + /* storage */ "", + /* execfunc */ node_composit_exec_viewer + }; /* **************** COMPOSITE ******************** */ static bNodeSocketType cmp_node_composite_in[]= { - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; /* applies to render pipeline */ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* image assigned to output */ - /* stack order input sockets: col, alpha, z */ - - if(node->flag & NODE_DO_OUTPUT) { /* only one works on out */ - RenderData *rd= data; - if(rd->scemode & R_DOCOMP) { - RenderResult *rr= RE_GetResult(RE_GetRender(G.scene->id.name)); /* G.scene is WEAK! */ - if(rr) { - CompBuf *outbuf, *zbuf=NULL; - - if(rr->rectf) - MEM_freeT(rr->rectf); - outbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 1); - - if(in[1]->data==NULL) - composit1_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, do_copy_rgba, CB_RGBA); - else - composit2_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL); - - if(in[2]->data) { - if(rr->rectz) - MEM_freeT(rr->rectz); - zbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VAL, 1); - composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value, CB_VAL); - rr->rectz= zbuf->rect; - zbuf->malloc= 0; - free_compbuf(zbuf); - } - generate_preview(node, outbuf); - - /* we give outbuf to rr... */ - rr->rectf= outbuf->rect; - outbuf->malloc= 0; - free_compbuf(outbuf); - - return; - } - } - } - if(in[0]->data) - generate_preview(node, in[0]->data); + /* image assigned to output */ + /* stack order input sockets: col, alpha, z */ + + if(node->flag & NODE_DO_OUTPUT) { /* only one works on out */ + RenderData *rd= data; + if(rd->scemode & R_DOCOMP) { + RenderResult *rr= RE_GetResult(RE_GetRender(G.scene->id.name)); /* G.scene is WEAK! */ + if(rr) { + CompBuf *outbuf, *zbuf=NULL; + + if(rr->rectf) + MEM_freeT(rr->rectf); + outbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 1); + + if(in[1]->data==NULL) + composit1_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, do_copy_rgba, CB_RGBA); + else + composit2_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL); + + if(in[2]->data) { + if(rr->rectz) + MEM_freeT(rr->rectz); + zbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VAL, 1); + composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value, CB_VAL); + rr->rectz= zbuf->rect; + zbuf->malloc= 0; + free_compbuf(zbuf); + } + generate_preview(node, outbuf); + + /* we give outbuf to rr... */ + rr->rectf= outbuf->rect; + outbuf->malloc= 0; + free_compbuf(outbuf); + + return; + } + } + } + if(in[0]->data) + generate_preview(node, in[0]->data); } static bNodeType cmp_node_composite= { - /* type code */ CMP_NODE_COMPOSITE, - /* name */ "Composite", - /* width+range */ 80, 60, 200, - /* class+opts */ NODE_CLASS_OUTPUT, NODE_PREVIEW, - /* input sock */ cmp_node_composite_in, - /* output sock */ NULL, - /* storage */ "", - /* execfunc */ node_composit_exec_composite - + /* type code */ CMP_NODE_COMPOSITE, + /* name */ "Composite", + /* width+range */ 80, 60, 200, + /* class+opts */ NODE_CLASS_OUTPUT, NODE_PREVIEW, + /* input sock */ cmp_node_composite_in, + /* output sock */ NULL, + /* storage */ "", + /* execfunc */ node_composit_exec_composite + }; /* **************** OUTPUT FILE ******************** */ static bNodeSocketType cmp_node_output_file_in[]= { - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void node_composit_exec_output_file(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* image assigned to output */ - /* stack order input sockets: col, alpha */ - - if(node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */ - } - else if(in[0]->data) - generate_preview(node, in[0]->data); + /* image assigned to output */ + /* stack order input sockets: col, alpha */ + + if(node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */ + } + else if(in[0]->data) + generate_preview(node, in[0]->data); } static bNodeType cmp_node_output_file= { - /* type code */ CMP_NODE_OUTPUT_FILE, - /* name */ "File Output", - /* width+range */ 80, 60, 200, - /* class+opts */ NODE_CLASS_FILE, NODE_PREVIEW, - /* input sock */ cmp_node_output_file_in, - /* output sock */ NULL, - /* storage */ "", - /* execfunc */ node_composit_exec_output_file - + /* type code */ CMP_NODE_OUTPUT_FILE, + /* name */ "File Output", + /* width+range */ 80, 60, 200, + /* class+opts */ NODE_CLASS_FILE, NODE_PREVIEW, + /* input sock */ cmp_node_output_file_in, + /* output sock */ NULL, + /* storage */ "", + /* execfunc */ node_composit_exec_output_file + }; /* **************** IMAGE ******************** */ static bNodeSocketType cmp_node_image_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static int calcimanr(int cfra, NodeImageAnim *nia) { - - if(nia->frames==0) return nia->nr; - - cfra= cfra - nia->sfra; - - /* cyclic */ - if(nia->cyclic) - cfra= (cfra % nia->frames); - else if(cfra>=nia->frames) - cfra= nia->frames-1; - else if(cfra<0) - cfra= 0; - - cfra+= nia->nr; - - if(cfra<1) cfra= 1; - - return cfra; + + if(nia->frames==0) return nia->nr; + + cfra= cfra - nia->sfra; + + /* cyclic */ + if(nia->cyclic) + cfra= (cfra % nia->frames); + else if(cfra>=nia->frames) + cfra= nia->frames-1; + else if(cfra<0) + cfra= 0; + + cfra+= nia->nr; + + if(cfra<1) cfra= 1; + + return cfra; } static void animated_image(bNode *node, int cfra) { - Image *ima; - NodeImageAnim *nia; - int imanr; - - ima= (Image *)node->id; - nia= node->storage; - - if(nia && nia->frames && ima && ima->name) { /* frames anim or movie */ - - imanr= calcimanr(cfra, nia); - - if(nia->movie) { - if(ima->anim==NULL) ima->anim = openanim(ima->name, IB_cmap | IB_rect); - if (ima->anim) { - int dur = IMB_anim_get_duration(ima->anim); - - if(imanr < 0) imanr = 0; - if(imanr > (dur-1)) imanr= dur-1; - - BLI_lock_thread(LOCK_MALLOC); - if(ima->ibuf) IMB_freeImBuf(ima->ibuf); - ima->ibuf = IMB_anim_absolute(ima->anim, imanr); - BLI_unlock_thread(LOCK_MALLOC); - - /* patch for textbutton with name ima (B_NAMEIMA) */ - if(ima->ibuf) { - strcpy(ima->ibuf->name, ima->name); - ima->ok= 1; - } - } - } - else { - - if(imanr!=ima->lastframe) { - unsigned short numlen; - char name[FILE_MAXDIR+FILE_MAXFILE], head[FILE_MAXDIR+FILE_MAXFILE], tail[FILE_MAXDIR+FILE_MAXFILE]; - - strcpy(name, ima->name); - - ima->lastframe= imanr; - - BLI_stringdec(name, head, tail, &numlen); - BLI_stringenc(name, head, tail, numlen, imanr); - - ima= add_image(name); - - if(ima) { - ima->flag |= IMA_FROMANIM; - if(node->id) node->id->us--; - node->id= (ID *)ima; - - ima->ok= 1; - } - } - } - } + Image *ima; + NodeImageAnim *nia; + int imanr; + + ima= (Image *)node->id; + nia= node->storage; + + if(nia && nia->frames && ima && ima->name) { /* frames anim or movie */ + + imanr= calcimanr(cfra, nia); + + if(nia->movie) { + if(ima->anim==NULL) ima->anim = openanim(ima->name, IB_cmap | IB_rect); + if (ima->anim) { + int dur = IMB_anim_get_duration(ima->anim); + + if(imanr < 0) imanr = 0; + if(imanr > (dur-1)) imanr= dur-1; + + BLI_lock_thread(LOCK_MALLOC); + if(ima->ibuf) IMB_freeImBuf(ima->ibuf); + ima->ibuf = IMB_anim_absolute(ima->anim, imanr); + BLI_unlock_thread(LOCK_MALLOC); + + /* patch for textbutton with name ima (B_NAMEIMA) */ + if(ima->ibuf) { + strcpy(ima->ibuf->name, ima->name); + ima->ok= 1; + } + } + } + else { + + if(imanr!=ima->lastframe) { + unsigned short numlen; + char name[FILE_MAXDIR+FILE_MAXFILE], head[FILE_MAXDIR+FILE_MAXFILE], tail[FILE_MAXDIR+FILE_MAXFILE]; + + strcpy(name, ima->name); + + ima->lastframe= imanr; + + BLI_stringdec(name, head, tail, &numlen); + BLI_stringenc(name, head, tail, numlen, imanr); + + ima= add_image(name); + + if(ima) { + ima->flag |= IMA_FROMANIM; + if(node->id) node->id->us--; + node->id= (ID *)ima; + + ima->ok= 1; + } + } + } + } } static float *float_from_byte_rect(int rectx, int recty, char *rect) { - /* quick method to convert byte to floatbuf */ - float *rect_float= MEM_mallocT(4*sizeof(float)*rectx*recty, "float rect"); - float *tof = rect_float; - int i; - - for (i = rectx*recty; i > 0; i--) { - tof[0] = ((float)rect[0])*(1.0f/255.0f); - tof[1] = ((float)rect[1])*(1.0f/255.0f); - tof[2] = ((float)rect[2])*(1.0f/255.0f); - tof[3] = ((float)rect[3])*(1.0f/255.0f); - rect += 4; - tof += 4; - } - return rect_float; + /* quick method to convert byte to floatbuf */ + float *rect_float= MEM_mallocT(4*sizeof(float)*rectx*recty, "float rect"); + float *tof = rect_float; + int i; + + for (i = rectx*recty; i > 0; i--) { + tof[0] = ((float)rect[0])*(1.0f/255.0f); + tof[1] = ((float)rect[1])*(1.0f/255.0f); + tof[2] = ((float)rect[2])*(1.0f/255.0f); + tof[3] = ((float)rect[3])*(1.0f/255.0f); + rect += 4; + tof += 4; + } + return rect_float; } static CompBuf *node_composit_get_image(bNode *node, RenderData *rd) { - Image *ima; - CompBuf *stackbuf; - - /* animated image? */ - if(node->storage) - animated_image(node, rd->cfra); - - ima= (Image *)node->id; - - /* test if image is OK */ - if(ima->ok==0) return NULL; - - if(ima->ibuf==NULL) { - BLI_lock_thread(LOCK_MALLOC); - load_image(ima, IB_rect, G.sce, rd->cfra); /* G.sce is current .blend path */ - BLI_unlock_thread(LOCK_MALLOC); - if(ima->ibuf==NULL) { - ima->ok= 0; - return NULL; - } - } - if(ima->ibuf->rect_float==NULL) { - /* can't use imbuf module, we need secure malloc */ - ima->ibuf->rect_float= float_from_byte_rect(ima->ibuf->x, ima->ibuf->y, (char *)ima->ibuf->rect); - ima->ibuf->mall |= IB_rectfloat; - } - - if(rd->scemode & R_COMP_CROP) { - stackbuf= get_cropped_compbuf(&rd->disprect, ima->ibuf->rect_float, ima->ibuf->x, ima->ibuf->y, CB_RGBA); - } - else { - /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */ - stackbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_RGBA, 0); - stackbuf->rect= ima->ibuf->rect_float; - } - - return stackbuf; + Image *ima; + CompBuf *stackbuf; + + /* animated image? */ + if(node->storage) + animated_image(node, rd->cfra); + + ima= (Image *)node->id; + + /* test if image is OK */ + if(ima->ok==0) return NULL; + + if(ima->ibuf==NULL) { + BLI_lock_thread(LOCK_MALLOC); + load_image(ima, IB_rect, G.sce, rd->cfra); /* G.sce is current .blend path */ + BLI_unlock_thread(LOCK_MALLOC); + if(ima->ibuf==NULL) { + ima->ok= 0; + return NULL; + } + } + if(ima->ibuf->rect_float==NULL) { + /* can't use imbuf module, we need secure malloc */ + ima->ibuf->rect_float= float_from_byte_rect(ima->ibuf->x, ima->ibuf->y, (char *)ima->ibuf->rect); + ima->ibuf->mall |= IB_rectfloat; + } + + if(rd->scemode & R_COMP_CROP) { + stackbuf= get_cropped_compbuf(&rd->disprect, ima->ibuf->rect_float, ima->ibuf->x, ima->ibuf->y, CB_RGBA); + } + else { + /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */ + stackbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_RGBA, 0); + stackbuf->rect= ima->ibuf->rect_float; + } + + return stackbuf; } static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd) { - Image *ima= (Image *)node->id; - CompBuf *zbuf= NULL; - - if(ima->ibuf && ima->ibuf->zbuf_float) { - if(rd->scemode & R_COMP_CROP) { - zbuf= get_cropped_compbuf(&rd->disprect, ima->ibuf->zbuf_float, ima->ibuf->x, ima->ibuf->y, CB_VAL); - } - else { - zbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_VAL, 0); - zbuf->rect= ima->ibuf->zbuf_float; - } - } - return zbuf; + Image *ima= (Image *)node->id; + CompBuf *zbuf= NULL; + + if(ima->ibuf && ima->ibuf->zbuf_float) { + if(rd->scemode & R_COMP_CROP) { + zbuf= get_cropped_compbuf(&rd->disprect, ima->ibuf->zbuf_float, ima->ibuf->x, ima->ibuf->y, CB_VAL); + } + else { + zbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_VAL, 0); + zbuf->rect= ima->ibuf->zbuf_float; + } + } + return zbuf; } static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - - /* image assigned to output */ - /* stack order input sockets: col, alpha */ - if(node->id) { - CompBuf *stackbuf= node_composit_get_image(node, data); - - /* put ibuf on stack */ - out[0]->data= stackbuf; - - if(stackbuf) { - if(out[1]->hasoutput) - out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); - - if(out[2]->hasoutput) - out[2]->data= node_composit_get_zimage(node, data); - - generate_preview(node, stackbuf); - } - } + + /* image assigned to output */ + /* stack order input sockets: col, alpha */ + if(node->id) { + CompBuf *stackbuf= node_composit_get_image(node, data); + + /* put ibuf on stack */ + out[0]->data= stackbuf; + + if(stackbuf) { + if(out[1]->hasoutput) + out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); + + if(out[2]->hasoutput) + out[2]->data= node_composit_get_zimage(node, data); + + generate_preview(node, stackbuf); + } + } } /* uses node->storage to indicate animated image */ static bNodeType cmp_node_image= { - /* type code */ CMP_NODE_IMAGE, - /* name */ "Image", - /* width+range */ 120, 80, 300, - /* class+opts */ NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS, - /* input sock */ NULL, - /* output sock */ cmp_node_image_out, - /* storage */ "NodeImageAnim", - /* execfunc */ node_composit_exec_image - + /* type code */ CMP_NODE_IMAGE, + /* name */ "Image", + /* width+range */ 120, 80, 300, + /* class+opts */ NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS, + /* input sock */ NULL, + /* output sock */ cmp_node_image_out, + /* storage */ "NodeImageAnim", + /* execfunc */ node_composit_exec_image + }; /* **************** RENDER RESULT ******************** */ @@ -921,1583 +921,1807 @@ #define RRES_OUT_RAY 10 static bNodeSocketType cmp_node_rlayers_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 0, "Speed", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, -// { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, -// { SOCK_RGBA, 0, "Diffuse", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, -// { SOCK_RGBA, 0, "Specular", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, -// { SOCK_RGBA, 0, "Shadow", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, -// { SOCK_RGBA, 0, "AO", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, -// { SOCK_RGBA, 0, "Ray", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 0, "Speed", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + // { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + // { SOCK_RGBA, 0, "Diffuse", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + // { SOCK_RGBA, 0, "Specular", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + // { SOCK_RGBA, 0, "Shadow", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + // { SOCK_RGBA, 0, "AO", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + // { SOCK_RGBA, 0, "Ray", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, int recty, int passcode) { - float *fp= RE_RenderLayerGetPass(rl, passcode); - if(fp) { - CompBuf *buf; - int buftype= CB_VEC3; - - if(passcode==SCE_PASS_Z) - buftype= CB_VAL; - else if(passcode==SCE_PASS_VECTOR) - buftype= CB_VEC4; - else if(passcode==SCE_PASS_RGBA) - buftype= CB_RGBA; - - if(rd->scemode & R_COMP_CROP) - buf= get_cropped_compbuf(&rd->disprect, fp, rectx, recty, buftype); - else { - buf= alloc_compbuf(rectx, recty, buftype, 0); - buf->rect= fp; - } - return buf; - } - return NULL; + float *fp= RE_RenderLayerGetPass(rl, passcode); + if(fp) { + CompBuf *buf; + int buftype= CB_VEC3; + + if(passcode==SCE_PASS_Z) + buftype= CB_VAL; + else if(passcode==SCE_PASS_VECTOR) + buftype= CB_VEC4; + else if(passcode==SCE_PASS_RGBA) + buftype= CB_RGBA; + + if(rd->scemode & R_COMP_CROP) + buf= get_cropped_compbuf(&rd->disprect, fp, rectx, recty, buftype); + else { + buf= alloc_compbuf(rectx, recty, buftype, 0); + buf->rect= fp; + } + return buf; + } + return NULL; } static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - Scene *sce= node->id?(Scene *)node->id:G.scene; /* G.scene is WEAK! */ - RenderData *rd= data; - RenderResult *rr; - - rr= RE_GetResult(RE_GetRender(sce->id.name)); - - if(rr) { - SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1); - if(srl) { - RenderLayer *rl= RE_GetRenderLayer(rr, srl->name); - if(rl && rl->rectf) { - CompBuf *stackbuf; - - /* we put render rect on stack, cbuf knows rect is from other ibuf when freed! */ - if(rd->scemode & R_COMP_CROP) - stackbuf= get_cropped_compbuf(&rd->disprect, rl->rectf, rr->rectx, rr->recty, CB_RGBA); - else { - stackbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 0); - stackbuf->rect= rl->rectf; - } - - stackbuf->xof= rr->xof; - stackbuf->yof= rr->yof; - - /* put on stack */ - out[RRES_OUT_IMAGE]->data= stackbuf; - - if(out[RRES_OUT_ALPHA]->hasoutput) - out[RRES_OUT_ALPHA]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); - if(out[RRES_OUT_Z]->hasoutput) - out[RRES_OUT_Z]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_Z); - if(out[RRES_OUT_VEC]->hasoutput) - out[RRES_OUT_VEC]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_VECTOR); - if(out[RRES_OUT_NOR]->hasoutput) - out[RRES_OUT_NOR]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_NORMAL); - /* - if(out[RRES_OUT_COL]->hasoutput) - out[RRES_OUT_COL]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_RGBA); - if(out[RRES_OUT_DIFF]->hasoutput) - out[RRES_OUT_DIFF]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_DIFFUSE); - if(out[RRES_OUT_SPEC]->hasoutput) - out[RRES_OUT_SPEC]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_SPEC); - if(out[RRES_OUT_SHAD]->hasoutput) - out[RRES_OUT_SHAD]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_SHADOW); - if(out[RRES_OUT_AO]->hasoutput) - out[RRES_OUT_AO]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_AO); - if(out[RRES_OUT_RAY]->hasoutput) - out[RRES_OUT_RAY]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_RAY); - */ - generate_preview(node, stackbuf); - } - } - } + Scene *sce= node->id?(Scene *)node->id:G.scene; /* G.scene is WEAK! */ + RenderData *rd= data; + RenderResult *rr; + + rr= RE_GetResult(RE_GetRender(sce->id.name)); + + if(rr) { + SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1); + if(srl) { + RenderLayer *rl= RE_GetRenderLayer(rr, srl->name); + if(rl && rl->rectf) { + CompBuf *stackbuf; + + /* we put render rect on stack, cbuf knows rect is from other ibuf when freed! */ + if(rd->scemode & R_COMP_CROP) + stackbuf= get_cropped_compbuf(&rd->disprect, rl->rectf, rr->rectx, rr->recty, CB_RGBA); + else { + stackbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 0); + stackbuf->rect= rl->rectf; + } + + stackbuf->xof= rr->xof; + stackbuf->yof= rr->yof; + + /* put on stack */ + out[RRES_OUT_IMAGE]->data= stackbuf; + + if(out[RRES_OUT_ALPHA]->hasoutput) + out[RRES_OUT_ALPHA]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); + if(out[RRES_OUT_Z]->hasoutput) + out[RRES_OUT_Z]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_Z); + if(out[RRES_OUT_VEC]->hasoutput) + out[RRES_OUT_VEC]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_VECTOR); + if(out[RRES_OUT_NOR]->hasoutput) + out[RRES_OUT_NOR]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_NORMAL); + /* + if(out[RRES_OUT_COL]->hasoutput) + out[RRES_OUT_COL]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_RGBA); + if(out[RRES_OUT_DIFF]->hasoutput) + out[RRES_OUT_DIFF]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_DIFFUSE); + if(out[RRES_OUT_SPEC]->hasoutput) + out[RRES_OUT_SPEC]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_SPEC); + if(out[RRES_OUT_SHAD]->hasoutput) + out[RRES_OUT_SHAD]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_SHADOW); + if(out[RRES_OUT_AO]->hasoutput) + out[RRES_OUT_AO]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_AO); + if(out[RRES_OUT_RAY]->hasoutput) + out[RRES_OUT_RAY]->data= compbuf_from_pass(rd, rl, rr->rectx, rr->recty, SCE_PASS_RAY); + */ + generate_preview(node, stackbuf); + } + } + } } /* custom1 = render layer in use */ /* custom2 = re-render tag */ static bNodeType cmp_node_rlayers= { - /* type code */ CMP_NODE_R_LAYERS, - /* name */ "Render Layers", - /* width+range */ 150, 100, 300, - /* class+opts */ NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS, - /* input sock */ NULL, - /* output sock */ cmp_node_rlayers_out, - /* storage */ "", - /* execfunc */ node_composit_exec_rlayers - + /* type code */ CMP_NODE_R_LAYERS, + /* name */ "Render Layers", + /* width+range */ 150, 100, 300, + /* class+opts */ NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS, + /* input sock */ NULL, + /* output sock */ cmp_node_rlayers_out, + /* storage */ "", + /* execfunc */ node_composit_exec_rlayers + }; /* **************** TEXTURE ******************** */ static bNodeSocketType cmp_node_texture_in[]= { - { SOCK_VECTOR, 0, "Offset", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f}, - { SOCK_VECTOR, 0, "Scale", 1.0f, 1.0f, 1.0f, 1.0f, -10.0f, 10.0f}, - { -1, 0, "" } + { SOCK_VECTOR, 0, "Offset", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f}, + { SOCK_VECTOR, 0, "Scale", 1.0f, 1.0f, 1.0f, 1.0f, -10.0f, 10.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_texture_out[]= { - { SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA , 0, "Color", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA , 0, "Color", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; /* called without rect allocated */ static void texture_procedural(CompBuf *cbuf, float *col, float xco, float yco) { - bNode *node= cbuf->node; - bNodeSocket *sock= node->inputs.first; - TexResult texres; - float vec[3], *size, nor[3]={0.0f, 0.0f, 0.0f}; - int retval, type= cbuf->type; - - texres.nor= NULL; - size= sock->next->ns.vec; - - vec[0]= size[0]*(xco + sock->ns.vec[0]); - vec[1]= size[1]*(yco + sock->ns.vec[1]); - vec[2]= size[2]*sock->ns.vec[2]; - - retval= multitex_ext((Tex *)node->id, vec, NULL, NULL, 0, &texres); - - if(type==CB_VAL) { - if(texres.talpha) - col[0]= texres.ta; - else - col[0]= texres.tin; - } - else if(type==CB_RGBA) { - if(texres.talpha) - col[3]= texres.ta; - else - col[3]= texres.tin; - - if((retval & TEX_RGB)) { - col[0]= texres.tr; - col[1]= texres.tg; - col[2]= texres.tb; - } - else col[0]= col[1]= col[2]= col[3]; - } - else { - VECCOPY(col, nor); - } + bNode *node= cbuf->node; + bNodeSocket *sock= node->inputs.first; + TexResult texres; + float vec[3], *size, nor[3]={0.0f, 0.0f, 0.0f}; + int retval, type= cbuf->type; + + texres.nor= NULL; + size= sock->next->ns.vec; + + vec[0]= size[0]*(xco + sock->ns.vec[0]); + vec[1]= size[1]*(yco + sock->ns.vec[1]); + vec[2]= size[2]*sock->ns.vec[2]; + + retval= multitex_ext((Tex *)node->id, vec, NULL, NULL, 0, &texres); + + if(type==CB_VAL) { + if(texres.talpha) + col[0]= texres.ta; + else + col[0]= texres.tin; + } + else if(type==CB_RGBA) { + if(texres.talpha) + col[3]= texres.ta; + else + col[3]= texres.tin; + + if((retval & TEX_RGB)) { + col[0]= texres.tr; + col[1]= texres.tg; + col[2]= texres.tb; + } + else col[0]= col[1]= col[2]= col[3]; + } + else { + VECCOPY(col, nor); + } } /* texture node outputs get a small rect, to make sure all other nodes accept it */ /* only the pixel-processor nodes do something with it though */ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* outputs: value, color, normal */ - - if(node->id) { - /* first make the preview image */ - CompBuf *prevbuf= alloc_compbuf(140, 140, CB_RGBA, 1); // alloc - - prevbuf->rect_procedural= texture_procedural; - prevbuf->node= node; - composit1_pixel_processor(node, prevbuf, prevbuf, out[0]->vec, do_copy_rgba, CB_RGBA); - generate_preview(node, prevbuf); - free_compbuf(prevbuf); - - if(out[0]->hasoutput) { - CompBuf *stackbuf= alloc_compbuf(140, 140, CB_VAL, 1); // alloc - - stackbuf->rect_procedural= texture_procedural; - stackbuf->node= node; - - out[0]->data= stackbuf; - } - if(out[1]->hasoutput) { - CompBuf *stackbuf= alloc_compbuf(140, 140, CB_RGBA, 1); // alloc - - stackbuf->rect_procedural= texture_procedural; - stackbuf->node= node; - - out[1]->data= stackbuf; - } - } + /* outputs: value, color, normal */ + + if(node->id) { + /* first make the preview image */ + CompBuf *prevbuf= alloc_compbuf(140, 140, CB_RGBA, 1); // alloc + + prevbuf->rect_procedural= texture_procedural; + prevbuf->node= node; + composit1_pixel_processor(node, prevbuf, prevbuf, out[0]->vec, do_copy_rgba, CB_RGBA); + generate_preview(node, prevbuf); + free_compbuf(prevbuf); + + if(out[0]->hasoutput) { + CompBuf *stackbuf= alloc_compbuf(140, 140, CB_VAL, 1); // alloc + + stackbuf->rect_procedural= texture_procedural; + stackbuf->node= node; + + out[0]->data= stackbuf; + } + if(out[1]->hasoutput) { + CompBuf *stackbuf= alloc_compbuf(140, 140, CB_RGBA, 1); // alloc + + stackbuf->rect_procedural= texture_procedural; + stackbuf->node= node; + + out[1]->data= stackbuf; + } + } } static bNodeType cmp_node_texture= { - /* type code */ CMP_NODE_TEXTURE, - /* name */ "Texture", - /* width+range */ 120, 80, 240, - /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW, - /* input sock */ cmp_node_texture_in, - /* output sock */ cmp_node_texture_out, - /* storage */ "", - /* execfunc */ node_composit_exec_texture - + /* type code */ CMP_NODE_TEXTURE, + /* name */ "Texture", + /* width+range */ 120, 80, 240, + /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW, + /* input sock */ cmp_node_texture_in, + /* output sock */ cmp_node_texture_out, + /* storage */ "", + /* execfunc */ node_composit_exec_texture + }; /* **************** NORMAL ******************** */ static bNodeSocketType cmp_node_normal_in[]= { - { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_normal_out[]= { - { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_VALUE, 0, "Dot", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_VALUE, 0, "Dot", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void do_normal(bNode *node, float *out, float *in) { - bNodeSocket *sock= node->outputs.first; - float *nor= sock->ns.vec; - - /* render normals point inside... the widget points outside */ - out[0]= -INPR(nor, in); + bNodeSocket *sock= node->outputs.first; + float *nor= sock->ns.vec; + + /* render normals point inside... the widget points outside */ + out[0]= -INPR(nor, in); } /* generates normal, does dot product */ static void node_composit_exec_normal(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - bNodeSocket *sock= node->outputs.first; - /* stack order input: normal */ - /* stack order output: normal, value */ - - /* input no image? then only vector op */ - if(in[0]->data==NULL) { - VECCOPY(out[0]->vec, sock->ns.vec); - /* render normals point inside... the widget points outside */ - out[1]->vec[0]= -INPR(out[0]->vec, in[0]->vec); - } - else if(out[1]->hasoutput) { - /* make output size of input image */ - CompBuf *cbuf= in[0]->data; - CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocs - - composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_normal, CB_VEC3); - - out[1]->data= stackbuf; - } - - + bNodeSocket *sock= node->outputs.first; + /* stack order input: normal */ + /* stack order output: normal, value */ + + /* input no image? then only vector op */ + if(in[0]->data==NULL) { + VECCOPY(out[0]->vec, sock->ns.vec); + /* render normals point inside... the widget points outside */ + out[1]->vec[0]= -INPR(out[0]->vec, in[0]->vec); + } + else if(out[1]->hasoutput) { + /* make output size of input image */ + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocs + + composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_normal, CB_VEC3); + + out[1]->data= stackbuf; + } + + } static bNodeType cmp_node_normal= { - /* type code */ CMP_NODE_NORMAL, - /* name */ "Normal", - /* width+range */ 100, 60, 200, - /* class+opts */ NODE_CLASS_OP_VECTOR, NODE_OPTIONS, - /* input sock */ cmp_node_normal_in, - /* output sock */ cmp_node_normal_out, - /* storage */ "", - /* execfunc */ node_composit_exec_normal - + /* type code */ CMP_NODE_NORMAL, + /* name */ "Normal", + /* width+range */ 100, 60, 200, + /* class+opts */ NODE_CLASS_OP_VECTOR, NODE_OPTIONS, + /* input sock */ cmp_node_normal_in, + /* output sock */ cmp_node_normal_out, + /* storage */ "", + /* execfunc */ node_composit_exec_normal + }; /* **************** CURVE Time ******************** */ /* custom1 = sfra, custom2 = efra */ static bNodeSocketType cmp_node_time_out[]= { - { SOCK_VALUE, 0, "Fac", 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 0, "Fac", 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void node_composit_exec_time(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order output: fac */ - float fac= 0.0f; - - if(node->custom1 < node->custom2) - fac= (G.scene->r.cfra - node->custom1)/(float)(node->custom2-node->custom1); - - out[0]->vec[0]= curvemapping_evaluateF(node->storage, 0, fac); + /* stack order output: fac */ + float fac= 0.0f; + + if(node->custom1 < node->custom2) + fac= (G.scene->r.cfra - node->custom1)/(float)(node->custom2-node->custom1); + + out[0]->vec[0]= curvemapping_evaluateF(node->storage, 0, fac); } static bNodeType cmp_node_time= { - /* type code */ CMP_NODE_TIME, - /* name */ "Time", - /* width+range */ 140, 100, 320, - /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS, - /* input sock */ NULL, - /* output sock */ cmp_node_time_out, - /* storage */ "CurveMapping", - /* execfunc */ node_composit_exec_time + /* type code */ CMP_NODE_TIME, + /* name */ "Time", + /* width+range */ 140, 100, 320, + /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS, + /* input sock */ NULL, + /* output sock */ cmp_node_time_out, + /* storage */ "CurveMapping", + /* execfunc */ node_composit_exec_time }; /* **************** CURVE VEC ******************** */ static bNodeSocketType cmp_node_curve_vec_in[]= { - { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_curve_vec_out[]= { - { SOCK_VECTOR, 0, "Vector", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VECTOR, 0, "Vector", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } }; static void node_composit_exec_curve_vec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order input: vec */ - /* stack order output: vec */ - - curvemapping_evaluate_premulRGBF(node->storage, out[0]->vec, in[0]->vec); + /* stack order input: vec */ + /* stack order output: vec */ + + curvemapping_evaluate_premulRGBF(node->storage, out[0]->vec, in[0]->vec); } static bNodeType cmp_node_curve_vec= { - /* type code */ CMP_NODE_CURVE_VEC, - /* name */ "Vector Curves", - /* width+range */ 200, 140, 320, - /* class+opts */ NODE_CLASS_OP_VECTOR, NODE_OPTIONS, - /* input sock */ cmp_node_curve_vec_in, - /* output sock */ cmp_node_curve_vec_out, - /* storage */ "CurveMapping", - /* execfunc */ node_composit_exec_curve_vec - + /* type code */ CMP_NODE_CURVE_VEC, + /* name */ "Vector Curves", + /* width+range */ 200, 140, 320, + /* class+opts */ NODE_CLASS_OP_VECTOR, NODE_OPTIONS, + /* input sock */ cmp_node_curve_vec_in, + /* output sock */ cmp_node_curve_vec_out, + /* storage */ "CurveMapping", + /* execfunc */ node_composit_exec_curve_vec + }; /* **************** CURVE RGB ******************** */ static bNodeSocketType cmp_node_curve_rgb_in[]= { - { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_curve_rgb_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } }; static void do_curves(bNode *node, float *out, float *in) { - curvemapping_evaluate_premulRGBF(node->storage, out, in); - out[3]= in[3]; + curvemapping_evaluate_premulRGBF(node->storage, out, in); + out[3]= in[3]; } static void do_curves_fac(bNode *node, float *out, float *in, float *fac) { - - if(*fac>=1.0) - curvemapping_evaluate_premulRGBF(node->storage, out, in); - else if(*fac<=0.0) { - VECCOPY(out, in); - } - else { - float col[4], mfac= 1.0f-*fac; - curvemapping_evaluate_premulRGBF(node->storage, col, in); - out[0]= mfac*in[0] + *fac*col[0]; - out[1]= mfac*in[1] + *fac*col[1]; - out[2]= mfac*in[2] + *fac*col[2]; - } - out[3]= in[3]; + + if(*fac>=1.0) + curvemapping_evaluate_premulRGBF(node->storage, out, in); + else if(*fac<=0.0) { + VECCOPY(out, in); + } + else { + float col[4], mfac= 1.0f-*fac; + curvemapping_evaluate_premulRGBF(node->storage, col, in); + out[0]= mfac*in[0] + *fac*col[0]; + out[1]= mfac*in[1] + *fac*col[1]; + out[2]= mfac*in[2] + *fac*col[2]; + } + out[3]= in[3]; } static void node_composit_exec_curve_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order input: fac, image */ - /* stack order output: image */ - - if(out[0]->hasoutput==0) - return; - - /* input no image? then only color operation */ - if(in[1]->data==NULL) { - curvemapping_evaluateRGBF(node->storage, out[0]->vec, in[1]->vec); - } - else { - /* make output size of input image */ - CompBuf *cbuf= in[1]->data; - CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs - - if(in[0]->data) - composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_curves_fac, CB_RGBA, CB_VAL); - else - composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_curves, CB_RGBA); - - out[0]->data= stackbuf; - } - + /* stack order input: fac, image */ + /* stack order output: image */ + + if(out[0]->hasoutput==0) + return; + + /* input no image? then only color operation */ + if(in[1]->data==NULL) { + curvemapping_evaluateRGBF(node->storage, out[0]->vec, in[1]->vec); + } + else { + /* make output size of input image */ + CompBuf *cbuf= in[1]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + if(in[0]->data) + composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_curves_fac, CB_RGBA, CB_VAL); + else + composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_curves, CB_RGBA); + + out[0]->data= stackbuf; + } + } static bNodeType cmp_node_curve_rgb= { - /* type code */ CMP_NODE_CURVE_RGB, - /* name */ "RGB Curves", - /* width+range */ 200, 140, 320, - /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS, - /* input sock */ cmp_node_curve_rgb_in, - /* output sock */ cmp_node_curve_rgb_out, - /* storage */ "CurveMapping", - /* execfunc */ node_composit_exec_curve_rgb - + /* type code */ CMP_NODE_CURVE_RGB, + /* name */ "RGB Curves", + /* width+range */ 200, 140, 320, + /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS, + /* input sock */ cmp_node_curve_rgb_in, + /* output sock */ cmp_node_curve_rgb_out, + /* storage */ "CurveMapping", + /* execfunc */ node_composit_exec_curve_rgb + }; /* **************** VALUE ******************** */ static bNodeSocketType cmp_node_value_out[]= { - { SOCK_VALUE, 0, "Value", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 0, "Value", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void node_composit_exec_value(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - bNodeSocket *sock= node->outputs.first; - - out[0]->vec[0]= sock->ns.vec[0]; + bNodeSocket *sock= node->outputs.first; + + out[0]->vec[0]= sock->ns.vec[0]; } static bNodeType cmp_node_value= { - /* type code */ CMP_NODE_VALUE, - /* name */ "Value", - /* width+range */ 80, 40, 120, - /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS, - /* input sock */ NULL, - /* output sock */ cmp_node_value_out, - /* storage */ "", - /* execfunc */ node_composit_exec_value - + /* type code */ CMP_NODE_VALUE, + /* name */ "Value", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS, + /* input sock */ NULL, + /* output sock */ cmp_node_value_out, + /* storage */ "", + /* execfunc */ node_composit_exec_value + }; /* **************** RGB ******************** */ static bNodeSocketType cmp_node_rgb_out[]= { - { SOCK_RGBA, 0, "RGBA", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "RGBA", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void node_composit_exec_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - bNodeSocket *sock= node->outputs.first; - - VECCOPY(out[0]->vec, sock->ns.vec); + bNodeSocket *sock= node->outputs.first; + + VECCOPY(out[0]->vec, sock->ns.vec); } static bNodeType cmp_node_rgb= { - /* type code */ CMP_NODE_RGB, - /* name */ "RGB", - /* width+range */ 100, 60, 140, - /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS, - /* input sock */ NULL, - /* output sock */ cmp_node_rgb_out, - /* storage */ "", - /* execfunc */ node_composit_exec_rgb - + /* type code */ CMP_NODE_RGB, + /* name */ "RGB", + /* width+range */ 100, 60, 140, + /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS, + /* input sock */ NULL, + /* output sock */ cmp_node_rgb_out, + /* storage */ "", + /* execfunc */ node_composit_exec_rgb + }; /* **************** Hue Saturation ******************** */ static bNodeSocketType cmp_node_hue_sat_in[]= { - { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_hue_sat_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void do_hue_sat_fac(bNode *node, float *out, float *in, float *fac) { - NodeHueSat *nhs= node->storage; - - if(*fac!=0.0f && (nhs->hue!=0.5f || nhs->sat!=1.0)) { - float col[3], hsv[3], mfac= 1.0f - *fac; - - rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2); - hsv[0]+= (nhs->hue - 0.5f); - if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0; - hsv[1]*= nhs->sat; - if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0; - hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2); - - out[0]= mfac*in[0] + *fac*col[0]; - out[1]= mfac*in[1] + *fac*col[1]; - out[2]= mfac*in[2] + *fac*col[2]; - out[3]= in[3]; - } - else { - QUATCOPY(out, in); - } + NodeHueSat *nhs= node->storage; + + if(*fac!=0.0f && (nhs->hue!=0.5f || nhs->sat!=1.0 || nhs->val!=1.0)) { + float col[3], hsv[3], mfac= 1.0f - *fac; + + rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2); + hsv[0]+= (nhs->hue - 0.5f); + if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0; + hsv[1]*= nhs->sat; + if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0; + hsv[2]*= nhs->val; + if(hsv[2]>1.0) hsv[2]= 1.0; else if(hsv[2]<0.0) hsv[2]= 0.0; + hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2); + + out[0]= mfac*in[0] + *fac*col[0]; + out[1]= mfac*in[1] + *fac*col[1]; + out[2]= mfac*in[2] + *fac*col[2]; + out[3]= in[3]; + } + else { + QUATCOPY(out, in); + } } static void node_composit_exec_hue_sat(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order in: Fac, Image */ - /* stack order out: Image */ - if(out[0]->hasoutput==0) return; - - /* input no image? then only color operation */ - if(in[1]->data==NULL) { - do_hue_sat_fac(node, out[0]->vec, in[1]->vec, in[0]->vec); - } - else { - /* make output size of input image */ - CompBuf *cbuf= in[1]->data; - CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs - - composit2_pixel_processor(node, stackbuf, cbuf, in[1]->vec, in[0]->data, in[0]->vec, do_hue_sat_fac, CB_RGBA, CB_VAL); + /* stack order in: Fac, Image */ + /* stack order out: Image */ + if(out[0]->hasoutput==0) return; + + /* input no image? then only color operation */ + if(in[1]->data==NULL) { + do_hue_sat_fac(node, out[0]->vec, in[1]->vec, in[0]->vec); + } + else { + /* make output size of input image */ + CompBuf *cbuf= in[1]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs - out[0]->data= stackbuf; - } + composit2_pixel_processor(node, stackbuf, cbuf, in[1]->vec, in[0]->data, in[0]->vec, do_hue_sat_fac, CB_RGBA, CB_VAL); + + out[0]->data= stackbuf; + } } static bNodeType cmp_node_hue_sat= { - /* type code */ CMP_NODE_HUE_SAT, - /* name */ "Hue Saturation", - /* width+range */ 150, 80, 250, - /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS, - /* input sock */ cmp_node_hue_sat_in, - /* output sock */ cmp_node_hue_sat_out, - /* storage */ "NodeHueSat", - /* execfunc */ node_composit_exec_hue_sat - + /* type code */ CMP_NODE_HUE_SAT, + /* name */ "Hue Saturation Value", + /* width+range */ 150, 80, 250, + /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS, + /* input sock */ cmp_node_hue_sat_in, + /* output sock */ cmp_node_hue_sat_out, + /* storage */ "NodeHueSat", + /* execfunc */ node_composit_exec_hue_sat + }; /* **************** MIX RGB ******************** */ static bNodeSocketType cmp_node_mix_rgb_in[]= { - { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_mix_rgb_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void do_mix_rgb(bNode *node, float *out, float *in1, float *in2, float *fac) { - float col[3]; - - VECCOPY(col, in1); - ramp_blend(node->custom1, col, col+1, col+2, fac[0], in2); - VECCOPY(out, col); - out[3]= in1[3]; + float col[3]; + + VECCOPY(col, in1); + ramp_blend(node->custom1, col, col+1, col+2, fac[0], in2); + VECCOPY(out, col); + out[3]= in1[3]; } static void node_composit_exec_mix_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order in: fac, Image, Image */ - /* stack order out: Image */ - float *fac= in[0]->vec; - - if(out[0]->hasoutput==0) return; - - /* input no image? then only color operation */ - if(in[1]->data==NULL && in[2]->data==NULL) { - do_mix_rgb(node, out[0]->vec, in[1]->vec, in[2]->vec, fac); - } - else { - /* make output size of first available input image */ - CompBuf *cbuf= in[1]->data?in[1]->data:in[2]->data; - CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs - - composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, fac, do_mix_rgb, CB_RGBA, CB_RGBA, CB_VAL); - - out[0]->data= stackbuf; - } + /* stack order in: fac, Image, Image */ + /* stack order out: Image */ + float *fac= in[0]->vec; + + if(out[0]->hasoutput==0) return; + + /* input no image? then only color operation */ + if(in[1]->data==NULL && in[2]->data==NULL) { + do_mix_rgb(node, out[0]->vec, in[1]->vec, in[2]->vec, fac); + } + else { + /* make output size of first available input image */ + CompBuf *cbuf= in[1]->data?in[1]->data:in[2]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, fac, do_mix_rgb, CB_RGBA, CB_RGBA, CB_VAL); + + out[0]->data= stackbuf; + } } /* custom1 = mix type */ static bNodeType cmp_node_mix_rgb= { - /* type code */ CMP_NODE_MIX_RGB, - /* name */ "Mix", - /* width+range */ 80, 40, 120, - /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS, - /* input sock */ cmp_node_mix_rgb_in, - /* output sock */ cmp_node_mix_rgb_out, - /* storage */ "", - /* execfunc */ node_composit_exec_mix_rgb - + /* type code */ CMP_NODE_MIX_RGB, + /* name */ "Mix", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS, + /* input sock */ cmp_node_mix_rgb_in, + /* output sock */ cmp_node_mix_rgb_out, + /* storage */ "", + /* execfunc */ node_composit_exec_mix_rgb + }; /* **************** FILTER ******************** */ static bNodeSocketType cmp_node_filter_in[]= { - { SOCK_VALUE, 1, "Fac", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 1, "Fac", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_filter_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void do_filter_edge(CompBuf *out, CompBuf *in, float *filter, float fac) { - float *row1, *row2, *row3; - float *fp, f1, f2, mfac= 1.0f-fac; - int rowlen, x, y, c, pix= in->type; - - rowlen= in->x; - - for(y=0; yy; y++) { - /* setup rows */ - if(y==0) row1= in->rect; - else row1= in->rect + pix*(y-1)*rowlen; - - row2= in->rect + y*pix*rowlen; - - if(y==in->y-1) row3= row2; - else row3= row2 + pix*rowlen; - - fp= out->rect + pix*y*rowlen; - - if(pix==CB_RGBA) { - QUATCOPY(fp, row2); - fp+= pix; - - for(x=2; xtype; + + rowlen= in->x; + + for(y=0; yy; y++) { + /* setup rows */ + if(y==0) row1= in->rect; + else row1= in->rect + pix*(y-1)*rowlen; + + row2= in->rect + y*pix*rowlen; + + if(y==in->y-1) row3= row2; + else row3= row2 + pix*rowlen; + + fp= out->rect + pix*y*rowlen; + + if(pix==CB_RGBA) { + QUATCOPY(fp, row2); + fp+= pix; + + for(x=2; xtype; - - rowlen= in->x; - - for(y=0; yy; y++) { - /* setup rows */ - if(y==0) row1= in->rect; - else row1= in->rect + pixlen*(y-1)*rowlen; - - row2= in->rect + y*pixlen*rowlen; - - if(y==in->y-1) row3= row2; - else row3= row2 + pixlen*rowlen; - - fp= out->rect + pixlen*(y)*rowlen; - - if(pixlen==1) { - fp[0]= row2[0]; - fp+= pixlen; - - for(x=2; xtype; + + rowlen= in->x; + + for(y=0; yy; y++) { + /* setup rows */ + if(y==0) row1= in->rect; + else row1= in->rect + pixlen*(y-1)*rowlen; + + row2= in->rect + y*pixlen*rowlen; + + if(y==in->y-1) row3= row2; + else row3= row2 + pixlen*rowlen; + + fp= out->rect + pixlen*(y)*rowlen; + + if(pixlen==1) { + fp[0]= row2[0]; + fp+= pixlen; + + for(x=2; xhasoutput==0) return; - - /* stack order in: Image */ - /* stack order out: Image */ - - if(in[1]->data) { - /* make output size of first available input image */ - CompBuf *cbuf= in[1]->data; - CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1); // allocs - - switch(node->custom1) { - case CMP_FILT_SOFT: - do_filter3(stackbuf, cbuf, soft, in[0]->vec[0]); - break; - case CMP_FILT_SHARP: - do_filter3(stackbuf, cbuf, sharp, in[0]->vec[0]); - break; - case CMP_FILT_LAPLACE: - do_filter3(stackbuf, cbuf, laplace, in[0]->vec[0]); - break; - case CMP_FILT_SOBEL: - do_filter_edge(stackbuf, cbuf, sobel, in[0]->vec[0]); - break; - case CMP_FILT_PREWITT: - do_filter_edge(stackbuf, cbuf, prewitt, in[0]->vec[0]); - break; - case CMP_FILT_KIRSCH: - do_filter_edge(stackbuf, cbuf, kirsch, in[0]->vec[0]); - break; - case CMP_FILT_SHADOW: - do_filter3(stackbuf, cbuf, shadow, in[0]->vec[0]); - break; - } - - out[0]->data= stackbuf; - } + static float soft[9]= {1/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 4/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 1/16.0f}; + float sharp[9]= {-1,-1,-1,-1,9,-1,-1,-1,-1}; + float laplace[9]= {-1/8.0f, -1/8.0f, -1/8.0f, -1/8.0f, 1.0f, -1/8.0f, -1/8.0f, -1/8.0f, -1/8.0f}; + float sobel[9]= {1,2,1,0,0,0,-1,-2,-1}; + float prewitt[9]= {1,1,1,0,0,0,-1,-1,-1}; + float kirsch[9]= {5,5,5,-3,-3,-3,-2,-2,-2}; + float shadow[9]= {1,2,1,0,1,0,-1,-2,-1}; + + if(out[0]->hasoutput==0) return; + + /* stack order in: Image */ + /* stack order out: Image */ + + if(in[1]->data) { + /* make output size of first available input image */ + CompBuf *cbuf= in[1]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1); // allocs + + switch(node->custom1) { + case CMP_FILT_SOFT: + do_filter3(stackbuf, cbuf, soft, in[0]->vec[0]); + break; + case CMP_FILT_SHARP: + do_filter3(stackbuf, cbuf, sharp, in[0]->vec[0]); + break; + case CMP_FILT_LAPLACE: + do_filter3(stackbuf, cbuf, laplace, in[0]->vec[0]); + break; + case CMP_FILT_SOBEL: + do_filter_edge(stackbuf, cbuf, sobel, in[0]->vec[0]); + break; + case CMP_FILT_PREWITT: + do_filter_edge(stackbuf, cbuf, prewitt, in[0]->vec[0]); + break; + case CMP_FILT_KIRSCH: + do_filter_edge(stackbuf, cbuf, kirsch, in[0]->vec[0]); + break; + case CMP_FILT_SHADOW: + do_filter3(stackbuf, cbuf, shadow, in[0]->vec[0]); + break; + } + + out[0]->data= stackbuf; + } } /* custom1 = filter type */ static bNodeType cmp_node_filter= { - /* type code */ CMP_NODE_FILTER, - /* name */ "Filter", - /* width+range */ 80, 40, 120, - /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS, - /* input sock */ cmp_node_filter_in, - /* output sock */ cmp_node_filter_out, - /* storage */ "", - /* execfunc */ node_composit_exec_filter - + /* type code */ CMP_NODE_FILTER, + /* name */ "Filter", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS, + /* input sock */ cmp_node_filter_in, + /* output sock */ cmp_node_filter_out, + /* storage */ "", + /* execfunc */ node_composit_exec_filter + }; /* **************** VALTORGB ******************** */ static bNodeSocketType cmp_node_valtorgb_in[]= { - { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_valtorgb_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void do_colorband_composit(bNode *node, float *out, float *in) { - do_colorband(node->storage, in[0], out); + do_colorband(node->storage, in[0], out); } static void node_composit_exec_valtorgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order in: fac */ - /* stack order out: col, alpha */ - - if(out[0]->hasoutput==0 && out[1]->hasoutput==0) - return; - - if(node->storage) { - /* input no image? then only color operation */ - if(in[0]->data==NULL) { - do_colorband(node->storage, in[0]->vec[0], out[0]->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 - - composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_colorband_composit, CB_VAL); - - out[0]->data= stackbuf; - - if(out[1]->hasoutput) - out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); + /* stack order in: fac */ + /* stack order out: col, alpha */ + + if(out[0]->hasoutput==0 && out[1]->hasoutput==0) + return; + + if(node->storage) { + /* input no image? then only color operation */ + if(in[0]->data==NULL) { + do_colorband(node->storage, in[0]->vec[0], out[0]->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 + + composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_colorband_composit, CB_VAL); + + out[0]->data= stackbuf; + + if(out[1]->hasoutput) + out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); - } - } + } + } } static bNodeType cmp_node_valtorgb= { - /* type code */ CMP_NODE_VALTORGB, - /* name */ "ColorRamp", - /* width+range */ 240, 200, 300, - /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS, - /* input sock */ cmp_node_valtorgb_in, - /* output sock */ cmp_node_valtorgb_out, - /* storage */ "ColorBand", - /* execfunc */ node_composit_exec_valtorgb - + /* type code */ CMP_NODE_VALTORGB, + /* name */ "ColorRamp", + /* width+range */ 240, 200, 300, + /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS, + /* input sock */ cmp_node_valtorgb_in, + /* output sock */ cmp_node_valtorgb_out, + /* storage */ "ColorBand", + /* execfunc */ node_composit_exec_valtorgb + }; /* **************** RGBTOBW ******************** */ static bNodeSocketType cmp_node_rgbtobw_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_rgbtobw_out[]= { - { SOCK_VALUE, 0, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 0, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void do_rgbtobw(bNode *node, float *out, float *in) { - out[0]= in[0]*0.35f + in[1]*0.45f + in[2]*0.2f; + out[0]= in[0]*0.35f + in[1]*0.45f + in[2]*0.2f; } static void node_composit_exec_rgbtobw(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order out: bw */ - /* stack order in: col */ - - if(out[0]->hasoutput==0) - return; - - /* input no image? then only color operation */ - if(in[0]->data==NULL) { - do_rgbtobw(node, out[0]->vec, in[0]->vec); - } - else { - /* make output size of input image */ - CompBuf *cbuf= in[0]->data; - CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocs - - composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_rgbtobw, CB_RGBA); - - out[0]->data= stackbuf; - } + /* stack order out: bw */ + /* stack order in: col */ + + if(out[0]->hasoutput==0) + return; + + /* input no image? then only color operation */ + if(in[0]->data==NULL) { + do_rgbtobw(node, out[0]->vec, in[0]->vec); + } + else { + /* make output size of input image */ + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocs + + composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_rgbtobw, CB_RGBA); + + out[0]->data= stackbuf; + } } static bNodeType cmp_node_rgbtobw= { - /* type code */ CMP_NODE_RGBTOBW, - /* name */ "RGB to BW", - /* width+range */ 80, 40, 120, - /* class+opts */ NODE_CLASS_CONVERTOR, 0, - /* input sock */ cmp_node_rgbtobw_in, - /* output sock */ cmp_node_rgbtobw_out, - /* storage */ "", - /* execfunc */ node_composit_exec_rgbtobw - + /* type code */ CMP_NODE_RGBTOBW, + /* name */ "RGB to BW", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_CONVERTOR, 0, + /* input sock */ cmp_node_rgbtobw_in, + /* output sock */ cmp_node_rgbtobw_out, + /* storage */ "", + /* execfunc */ node_composit_exec_rgbtobw + }; /* **************** SEPARATE RGBA ******************** */ static bNodeSocketType cmp_node_seprgba_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_seprgba_out[]= { - { SOCK_VALUE, 0, "R", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "G", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "B", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "A", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 0, "R", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "G", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "B", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "A", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void node_composit_exec_seprgba(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order out: bw channels */ - /* stack order in: col */ - - /* input no image? then only color operation */ - if(in[0]->data==NULL) { - out[0]->vec[0] = in[0]->vec[0]; - out[1]->vec[0] = in[0]->vec[1]; - out[2]->vec[0] = in[0]->vec[2]; - out[3]->vec[0] = in[0]->vec[3]; - } - else { - /* make sure we get right rgba buffer */ - CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); - - /* don't do any pixel processing, just copy the stack directly (faster, I presume) */ - if(out[0]->hasoutput) - out[0]->data= valbuf_from_rgbabuf(cbuf, CHAN_R); - if(out[1]->hasoutput) - out[1]->data= valbuf_from_rgbabuf(cbuf, CHAN_G); - if(out[2]->hasoutput) - out[2]->data= valbuf_from_rgbabuf(cbuf, CHAN_B); - if(out[3]->hasoutput) - out[3]->data= valbuf_from_rgbabuf(cbuf, CHAN_A); - - if(cbuf!=in[0]->data) - free_compbuf(cbuf); + /* stack order out: bw channels */ + /* stack order in: col */ - } + /* input no image? then only color operation */ + if(in[0]->data==NULL) { + out[0]->vec[0] = in[0]->vec[0]; + out[1]->vec[0] = in[0]->vec[1]; + out[2]->vec[0] = in[0]->vec[2]; + out[3]->vec[0] = in[0]->vec[3]; + } + else { + /* make sure we get right rgba buffer */ + CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); + + /* don't do any pixel processing, just copy the stack directly (faster, I presume) */ + if(out[0]->hasoutput) + out[0]->data= valbuf_from_rgbabuf(cbuf, CHAN_R); + if(out[1]->hasoutput) + out[1]->data= valbuf_from_rgbabuf(cbuf, CHAN_G); + if(out[2]->hasoutput) + out[2]->data= valbuf_from_rgbabuf(cbuf, CHAN_B); + if(out[3]->hasoutput) + out[3]->data= valbuf_from_rgbabuf(cbuf, CHAN_A); + + if(cbuf!=in[0]->data) + free_compbuf(cbuf); + + } } static bNodeType cmp_node_seprgba= { - /* type code */ CMP_NODE_SEPRGBA, - /* name */ "Separate RGBA", - /* width+range */ 80, 40, 140, - /* class+opts */ NODE_CLASS_CONVERTOR, 0, - /* input sock */ cmp_node_seprgba_in, - /* output sock */ cmp_node_seprgba_out, - /* storage */ "", - /* execfunc */ node_composit_exec_seprgba - + /* type code */ CMP_NODE_SEPRGBA, + /* name */ "Separate RGBA", + /* width+range */ 80, 40, 140, + /* class+opts */ NODE_CLASS_CONVERTOR, 0, + /* input sock */ cmp_node_seprgba_in, + /* output sock */ cmp_node_seprgba_out, + /* storage */ "", + /* execfunc */ node_composit_exec_seprgba + +}; + +/* **************** COMBINE RGBA ******************** */ +static bNodeSocketType cmp_node_combrgba_in[]= { + { SOCK_VALUE, 1, "R", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "G", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "B", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "A", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType cmp_node_combrgba_out[]= { + { SOCK_RGBA, 0, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void do_combrgba(bNode *node, float *out, float *in1, float *in2, float *in3, float *in4) +{ + out[0] = in1[0]; + out[1] = in2[0]; + out[2] = in3[0]; + out[3] = in4[0]; +} + +static void node_composit_exec_combrgba(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order out: 1 rgba channels */ + /* stack order in: 4 value channels */ + + /* input no image? then only color operation */ + if((in[0]->data==NULL) && (in[1]->data==NULL) && (in[2]->data==NULL) && (in[3]->data==NULL)) { + out[0]->vec[0] = in[0]->vec[0]; + out[0]->vec[1] = in[1]->vec[0]; + out[0]->vec[2] = in[2]->vec[0]; + out[0]->vec[3] = in[3]->vec[0]; + } + else { + /* make output size of first available input image */ + CompBuf *cbuf; + CompBuf *stackbuf; + + if (in[0]->data) cbuf = in[0]->data; + else if (in[1]->data) cbuf = in[1]->data; + else if (in[2]->data) cbuf = in[2]->data; + else if (in[3]->data) cbuf = in[3]->data; + + stackbuf = alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, + in[2]->data, in[2]->vec, in[3]->data, in[3]->vec, + do_combrgba, CB_VAL, CB_VAL, CB_VAL, CB_VAL); + + out[0]->data= stackbuf; + } +} + +static bNodeType cmp_node_combrgba= { + /* type code */ CMP_NODE_COMBRGBA, + /* name */ "Combine RGBA", + /* width+range */ 80, 40, 140, + /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS, + /* input sock */ cmp_node_combrgba_in, + /* output sock */ cmp_node_combrgba_out, + /* storage */ "", + /* execfunc */ node_composit_exec_combrgba + }; + /* **************** SEPARATE HSVA ******************** */ static bNodeSocketType cmp_node_sephsva_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_sephsva_out[]= { - { SOCK_VALUE, 0, "H", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "S", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "V", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "A", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 0, "H", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "S", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "V", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "A", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void do_sephsva(bNode *node, float *out, float *in) { - float h, s, v; - - rgb_to_hsv(in[0], in[1], in[2], &h, &s, &v); - - out[0]= h; - out[1]= s; - out[2]= v; - out[3]= in[3]; + float h, s, v; + + rgb_to_hsv(in[0], in[1], in[2], &h, &s, &v); + + out[0]= h; + out[1]= s; + out[2]= v; + out[3]= in[3]; } static void node_composit_exec_sephsva(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order out: bw channels */ - /* stack order in: col */ + /* stack order out: bw channels */ + /* stack order in: col */ + + /* input no image? then only color operation */ + if(in[0]->data==NULL) { + float h, s, v; + + rgb_to_hsv(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &h, &s, &v); + + out[0]->vec[0] = h; + out[1]->vec[0] = s; + out[2]->vec[0] = v; + out[3]->vec[0] = in[0]->vec[3]; + } + else if ((out[0]->hasoutput) || (out[1]->hasoutput) || (out[2]->hasoutput) || (out[3]->hasoutput)) { + /* make output size of input image */ + CompBuf *cbuf= in[0]->data; + + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + /* convert the RGB stackbuf to an HSV representation */ + composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_sephsva, CB_RGBA); + + /* separate each of those channels */ + if(out[0]->hasoutput) + out[0]->data= valbuf_from_rgbabuf(stackbuf, CHAN_R); + if(out[1]->hasoutput) + out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_G); + if(out[2]->hasoutput) + out[2]->data= valbuf_from_rgbabuf(stackbuf, CHAN_B); + if(out[3]->hasoutput) + out[3]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); - /* input no image? then only color operation */ - if(in[0]->data==NULL) { - float h, s, v; - - rgb_to_hsv(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &h, &s, &v); - - out[0]->vec[0] = h; - out[1]->vec[0] = s; - out[2]->vec[0] = v; - out[3]->vec[0] = in[0]->vec[3]; - } - else if ((out[0]->hasoutput) || (out[1]->hasoutput) || (out[2]->hasoutput) || (out[3]->hasoutput)) { - /* make output size of input image */ - CompBuf *cbuf= in[0]->data; - - CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs - - /* convert the RGB stackbuf to an HSV representation */ - composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_sephsva, CB_RGBA); - - /* separate each of those channels */ - if(out[0]->hasoutput) - out[0]->data= valbuf_from_rgbabuf(stackbuf, CHAN_R); - if(out[1]->hasoutput) - out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_G); - if(out[2]->hasoutput) - out[2]->data= valbuf_from_rgbabuf(stackbuf, CHAN_B); - if(out[3]->hasoutput) - out[3]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); - - free_compbuf(stackbuf); - } + free_compbuf(stackbuf); + } } static bNodeType cmp_node_sephsva= { - /* type code */ CMP_NODE_SEPHSVA, - /* name */ "Separate HSVA", - /* width+range */ 80, 40, 140, - /* class+opts */ NODE_CLASS_CONVERTOR, 0, - /* input sock */ cmp_node_sephsva_in, - /* output sock */ cmp_node_sephsva_out, - /* storage */ "", - /* execfunc */ node_composit_exec_sephsva - + /* type code */ CMP_NODE_SEPHSVA, + /* name */ "Separate HSVA", + /* width+range */ 80, 40, 140, + /* class+opts */ NODE_CLASS_CONVERTOR, 0, + /* input sock */ cmp_node_sephsva_in, + /* output sock */ cmp_node_sephsva_out, + /* storage */ "", + /* execfunc */ node_composit_exec_sephsva + +}; + + +/* **************** SEPARATE YUVA ******************** */ +static bNodeSocketType cmp_node_sepyuva_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; +static bNodeSocketType cmp_node_sepyuva_out[]= { + { SOCK_VALUE, 0, "Y", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "U", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "V", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "A", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void do_sepyuva(bNode *node, float *out, float *in) +{ + float y, u, v; + + rgb_to_yuv(in[0], in[1], in[2], &y, &u, &v); + + out[0]= y; + out[1]= u; + out[2]= v; + out[3]= in[3]; +} + +static void node_composit_exec_sepyuva(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order out: bw channels */ + /* stack order in: col */ + + /* input no image? then only color operation */ + if(in[0]->data==NULL) { + float y, u, v; + + rgb_to_yuv(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &u, &v); + + out[0]->vec[0] = y; + out[1]->vec[0] = u; + out[2]->vec[0] = v; + out[3]->vec[0] = in[0]->vec[3]; + } + else if ((out[0]->hasoutput) || (out[1]->hasoutput) || (out[2]->hasoutput) || (out[3]->hasoutput)) { + /* make output size of input image */ + CompBuf *cbuf= in[0]->data; + + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + /* convert the RGB stackbuf to an HSV representation */ + composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_sepyuva, CB_RGBA); + + /* separate each of those channels */ + if(out[0]->hasoutput) + out[0]->data= valbuf_from_rgbabuf(stackbuf, CHAN_R); + if(out[1]->hasoutput) + out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_G); + if(out[2]->hasoutput) + out[2]->data= valbuf_from_rgbabuf(stackbuf, CHAN_B); + if(out[3]->hasoutput) + out[3]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); + + free_compbuf(stackbuf); + } +} + +static bNodeType cmp_node_sepyuva= { + /* type code */ CMP_NODE_SEPYUVA, + /* name */ "Separate YUVA", + /* width+range */ 80, 40, 140, + /* class+opts */ NODE_CLASS_CONVERTOR, 0, + /* input sock */ cmp_node_sepyuva_in, + /* output sock */ cmp_node_sepyuva_out, + /* storage */ "", + /* execfunc */ node_composit_exec_sepyuva + +}; + +/* **************** SEPARATE YCCA ******************** */ +static bNodeSocketType cmp_node_sepycca_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType cmp_node_sepycca_out[]= { + { SOCK_VALUE, 0, "Y", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Cb", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Cr", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "A", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void do_sepycca(bNode *node, float *out, float *in) +{ + float y, cb, cr; + + rgb_to_ycc(in[0], in[1], in[2], &y, &cb, &cr); + + //divided by 255 to normalize for viewing in + out[0]= y/255.0; + out[1]= cb/255.0; + out[2]= cr/255.0; + out[3]= in[3]; +} + +static void node_composit_exec_sepycca(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order out: bw channels */ + /* stack order in: col */ + + /* input no image? then only color operation */ + if(in[0]->data==NULL) { + float y, cb, cr; + + rgb_to_ycc(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &cb, &cr); + + //divided by 255 to normalize for viewing in + out[0]->vec[0] = y/255.0; + out[1]->vec[0] = cb/255.0; + out[2]->vec[0] = cr/255.0; + out[3]->vec[0] = in[0]->vec[3]; + } + else if ((out[0]->hasoutput) || (out[1]->hasoutput) || (out[2]->hasoutput) || (out[3]->hasoutput)) { + /* make output size of input image */ + CompBuf *cbuf= in[0]->data; + + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + /* convert the RGB stackbuf to an HSV representation */ + composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_sepycca, CB_RGBA); + + /* separate each of those channels */ + if(out[0]->hasoutput) + out[0]->data= valbuf_from_rgbabuf(stackbuf, CHAN_R); + if(out[1]->hasoutput) + out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_G); + if(out[2]->hasoutput) + out[2]->data= valbuf_from_rgbabuf(stackbuf, CHAN_B); + if(out[3]->hasoutput) + out[3]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); + + free_compbuf(stackbuf); + } +} + +static bNodeType cmp_node_sepycca= { + /* type code */ CMP_NODE_SEPYCCA, + /* name */ "Separate YCbCrA", + /* width+range */ 80, 40, 140, + /* class+opts */ NODE_CLASS_CONVERTOR, 0, + /* input sock */ cmp_node_sepycca_in, + /* output sock */ cmp_node_sepycca_out, + /* storage */ "", + /* execfunc */ node_composit_exec_sepycca + +}; + /* **************** SET ALPHA ******************** */ static bNodeSocketType cmp_node_setalpha_in[]= { - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_setalpha_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } }; static void node_composit_exec_setalpha(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order out: RGBA image */ - /* stack order in: col, alpha */ - - /* input no image? then only color operation */ - if(in[0]->data==NULL) { - out[0]->vec[0] = in[0]->vec[0]; - out[0]->vec[1] = in[0]->vec[1]; - out[0]->vec[2] = in[0]->vec[2]; - out[0]->vec[3] = in[1]->vec[0]; - } - else { - /* make output size of input image */ - CompBuf *cbuf= in[0]->data; - CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs - - if(in[1]->data==NULL && in[1]->vec[0]==1.0f) { - /* pass on image */ - composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_copy_rgb, CB_RGBA); - } - else { - /* send an compbuf or a value to set as alpha - composit2_pixel_processor handles choosing the right one */ - composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL); - } - - out[0]->data= stackbuf; - } + /* stack order out: RGBA image */ + /* stack order in: col, alpha */ + + /* input no image? then only color operation */ + if(in[0]->data==NULL) { + out[0]->vec[0] = in[0]->vec[0]; + out[0]->vec[1] = in[0]->vec[1]; + out[0]->vec[2] = in[0]->vec[2]; + out[0]->vec[3] = in[1]->vec[0]; + } + else { + /* make output size of input image */ + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + if(in[1]->data==NULL && in[1]->vec[0]==1.0f) { + /* pass on image */ + composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_copy_rgb, CB_RGBA); + } + else { + /* send an compbuf or a value to set as alpha - composit2_pixel_processor handles choosing the right one */ + composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL); + } + + out[0]->data= stackbuf; + } } static bNodeType cmp_node_setalpha= { - /* type code */ CMP_NODE_SETALPHA, - /* name */ "Set Alpha", - /* width+range */ 120, 40, 140, - /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS, - /* input sock */ cmp_node_setalpha_in, - /* output sock */ cmp_node_setalpha_out, - /* storage */ "", - /* execfunc */ node_composit_exec_setalpha - + /* type code */ CMP_NODE_SETALPHA, + /* name */ "Set Alpha", + /* width+range */ 120, 40, 140, + /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS, + /* input sock */ cmp_node_setalpha_in, + /* output sock */ cmp_node_setalpha_out, + /* storage */ "", + /* execfunc */ node_composit_exec_setalpha + }; /* **************** ALPHAOVER ******************** */ static bNodeSocketType cmp_node_alphaover_in[]= { - { SOCK_VALUE, 0, "Fac", 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 0, "Fac", 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_alphaover_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void do_alphaover_premul(bNode *node, float *out, float *src, float *over, float *fac) { - - if(over[3]<=0.0f) { - QUATCOPY(out, src); - } - else if(*fac==1.0f && over[3]>=1.0f) { - QUATCOPY(out, over); - } - else { - float mul= 1.0f - *fac*over[3]; - - out[0]= (mul*src[0]) + *fac*over[0]; - out[1]= (mul*src[1]) + *fac*over[1]; - out[2]= (mul*src[2]) + *fac*over[2]; - out[3]= (mul*src[3]) + *fac*over[3]; - } + + if(over[3]<=0.0f) { + QUATCOPY(out, src); + } + else if(*fac==1.0f && over[3]>=1.0f) { + QUATCOPY(out, over); + } + else { + float mul= 1.0f - *fac*over[3]; + + out[0]= (mul*src[0]) + *fac*over[0]; + out[1]= (mul*src[1]) + *fac*over[1]; + out[2]= (mul*src[2]) + *fac*over[2]; + out[3]= (mul*src[3]) + *fac*over[3]; + } } /* result will be still premul, but the over part is premulled */ static void do_alphaover_key(bNode *node, float *out, float *src, float *over, float *fac) { - - if(over[3]<=0.0f) { - QUATCOPY(out, src); - } - else if(*fac==1.0f && over[3]>=1.0f) { - QUATCOPY(out, over); - } - else { - float premul= fac[0]*over[3]; - float mul= 1.0f - premul; - - 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]) + fac[0]*over[3]; - } + + if(over[3]<=0.0f) { + QUATCOPY(out, src); + } + else if(*fac==1.0f && over[3]>=1.0f) { + QUATCOPY(out, over); + } + else { + float premul= fac[0]*over[3]; + float mul= 1.0f - premul; + + 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]) + fac[0]*over[3]; + } } static void node_composit_exec_alphaover(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order in: col col */ - /* stack order out: col */ - if(out[0]->hasoutput==0) - return; - - /* input no image? then only color operation */ - if(in[1]->data==NULL) { - do_alphaover_premul(node, out[0]->vec, in[1]->vec, in[2]->vec, in[0]->vec); - } - else { - /* make output size of input image */ - CompBuf *cbuf= in[1]->data; - CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs - - if(node->custom1) - composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_key, CB_RGBA, CB_RGBA, CB_VAL); - else - composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_premul, CB_RGBA, CB_RGBA, CB_VAL); - - out[0]->data= stackbuf; - } + /* stack order in: col col */ + /* stack order out: col */ + if(out[0]->hasoutput==0) + return; + + /* input no image? then only color operation */ + if(in[1]->data==NULL) { + do_alphaover_premul(node, out[0]->vec, in[1]->vec, in[2]->vec, in[0]->vec); + } + else { + /* make output size of input image */ + CompBuf *cbuf= in[1]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + if(node->custom1) + composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_key, CB_RGBA, CB_RGBA, CB_VAL); + else + composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_premul, CB_RGBA, CB_RGBA, CB_VAL); + + 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_OP_COLOR, NODE_OPTIONS, - /* input sock */ cmp_node_alphaover_in, - /* output sock */ cmp_node_alphaover_out, - /* storage */ "", - /* execfunc */ node_composit_exec_alphaover - + /* type code */ CMP_NODE_ALPHAOVER, + /* name */ "AlphaOver", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS, + /* input sock */ cmp_node_alphaover_in, + /* output sock */ cmp_node_alphaover_out, + /* storage */ "", + /* execfunc */ node_composit_exec_alphaover + }; /* **************** Z COMBINE ******************** */ static bNodeSocketType cmp_node_zcombine_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_zcombine_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void do_zcombine(bNode *node, float *out, float *src1, float *z1, float *src2, float *z2) { - if(*z1 <= *z2) { - QUATCOPY(out, src1); - } - else { - QUATCOPY(out, src2); - } + if(*z1 <= *z2) { + QUATCOPY(out, src1); + } + else { + QUATCOPY(out, src2); + } } static void node_composit_exec_zcombine(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order in: col z col z */ - /* stack order out: col z */ - if(out[0]->hasoutput==0) - return; - - /* no input no image do nothing now */ - if(in[0]->data==NULL || in[1]->data==NULL || in[2]->data==NULL || in[3]->data==NULL) { - return; - } - else { - /* make output size of first input image */ - CompBuf *cbuf= in[0]->data; - CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs - - composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, - in[3]->data, in[3]->vec, do_zcombine, CB_RGBA, CB_VAL, CB_RGBA, CB_VAL); - - out[0]->data= stackbuf; - } + /* stack order in: col z col z */ + /* stack order out: col z */ + if(out[0]->hasoutput==0) + return; + + /* no input no image do nothing now */ + if(in[0]->data==NULL || in[1]->data==NULL || in[2]->data==NULL || in[3]->data==NULL) { + return; + } + else { + /* make output size of first input image */ + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, + in[3]->data, in[3]->vec, do_zcombine, CB_RGBA, CB_VAL, CB_RGBA, CB_VAL); + + out[0]->data= stackbuf; + } } static bNodeType cmp_node_zcombine= { - /* type code */ CMP_NODE_ZCOMBINE, - /* name */ "Z Combine", - /* width+range */ 80, 40, 120, - /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS, - /* input sock */ cmp_node_zcombine_in, - /* output sock */ cmp_node_zcombine_out, - /* storage */ "", - /* execfunc */ node_composit_exec_zcombine - + /* type code */ CMP_NODE_ZCOMBINE, + /* name */ "Z Combine", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS, + /* input sock */ cmp_node_zcombine_in, + /* output sock */ cmp_node_zcombine_out, + /* storage */ "", + /* execfunc */ node_composit_exec_zcombine + }; /* **************** MAP VALUE ******************** */ static bNodeSocketType cmp_node_map_value_in[]= { - { SOCK_VALUE, 1, "Value", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 1, "Value", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_map_value_out[]= { - { SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void do_map_value(bNode *node, float *out, float *src) { - TexMapping *texmap= node->storage; - - out[0]= (src[0] + texmap->loc[0])*texmap->size[0]; - if(texmap->flag & TEXMAP_CLIP_MIN) - if(out[0]min[0]) - out[0]= texmap->min[0]; - if(texmap->flag & TEXMAP_CLIP_MAX) - if(out[0]>texmap->max[0]) - out[0]= texmap->max[0]; + TexMapping *texmap= node->storage; + + out[0]= (src[0] + texmap->loc[0])*texmap->size[0]; + if(texmap->flag & TEXMAP_CLIP_MIN) + if(out[0]min[0]) + out[0]= texmap->min[0]; + if(texmap->flag & TEXMAP_CLIP_MAX) + if(out[0]>texmap->max[0]) + out[0]= texmap->max[0]; } static void node_composit_exec_map_value(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order in: valbuf */ - /* stack order out: valbuf */ - if(out[0]->hasoutput==0) return; - - /* input no image? then only value operation */ - if(in[0]->data==NULL) { - do_map_value(node, out[0]->vec, in[0]->vec); - } - else { - /* make output size of input image */ - CompBuf *cbuf= in[0]->data; - CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocs - - composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_map_value, CB_VAL); - - out[0]->data= stackbuf; - } + /* stack order in: valbuf */ + /* stack order out: valbuf */ + if(out[0]->hasoutput==0) return; + + /* input no image? then only value operation */ + if(in[0]->data==NULL) { + do_map_value(node, out[0]->vec, in[0]->vec); + } + else { + /* make output size of input image */ + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocs + + composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_map_value, CB_VAL); + + out[0]->data= stackbuf; + } } static bNodeType cmp_node_map_value= { - /* type code */ CMP_NODE_MAP_VALUE, - /* name */ "Map Value", - /* width+range */ 100, 60, 150, - /* class+opts */ NODE_CLASS_OP_VECTOR, NODE_OPTIONS, - /* input sock */ cmp_node_map_value_in, - /* output sock */ cmp_node_map_value_out, - /* storage */ "TexMapping", - /* execfunc */ node_composit_exec_map_value - + /* type code */ CMP_NODE_MAP_VALUE, + /* name */ "Map Value", + /* width+range */ 100, 60, 150, + /* class+opts */ NODE_CLASS_OP_VECTOR, NODE_OPTIONS, + /* input sock */ cmp_node_map_value_in, + /* output sock */ cmp_node_map_value_out, + /* storage */ "TexMapping", + /* execfunc */ node_composit_exec_map_value + }; /* **************** BLUR ******************** */ static bNodeSocketType cmp_node_blur_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Size", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Size", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_blur_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static float *make_gausstab(int filtertype, int rad) { - float *gausstab, sum, val; - int i, n; - - n = 2 * rad + 1; - - gausstab = (float *) MEM_mallocT(n * sizeof(float), "gauss"); - - sum = 0.0f; - for (i = -rad; i <= rad; i++) { - val= RE_filter_value(filtertype, (float)i/(float)rad); - sum += val; - gausstab[i+rad] = val; - } - - sum= 1.0f/sum; - for(i=0; ix, imgy= img->y; - int x, y, pix= img->type; - int i, bigstep; - float *src, *dest; - - /* helper image */ - work= alloc_compbuf(imgx, imgy, img->type, 1); // allocs - - /* horizontal */ - rad = scale*(float)nbd->sizex; - if(rad>imgx/2) - rad= imgx/2; - else if(rad<1) - rad= 1; - - gausstab= make_gausstab(nbd->filtertype, rad); - gausstabcent= gausstab+rad; - - for (y = 0; y < imgy; y++) { - float *srcd= img->rect + pix*(y*img->x); - - dest = work->rect + pix*(y * img->x); - - for (x = 0; x < imgx ; x++) { - int minr= x-rad<0?-x:-rad; - int maxr= x+rad>imgx?imgx-x:rad; - - src= srcd + pix*(x+minr); - - sum= gval = rval= bval= aval= 0.0f; - for (i= minr; i < maxr; i++) { - val= gausstabcent[i]; - sum+= val; - rval += val * (*src++); - if(pix==4) { - gval += val * (*src++); - bval += val * (*src++); - aval += val * (*src++); - } - } - sum= 1.0f/sum; - *dest++ = rval*sum; - if(pix==4) { - *dest++ = gval*sum; - *dest++ = bval*sum; - *dest++ = aval*sum; - } - } - } - - /* vertical */ - MEM_freeT(gausstab); - - rad = scale*(float)nbd->sizey; - if(rad>imgy/2) - rad= imgy/2; - else if(rad<1) - rad= 1; - - gausstab= make_gausstab(nbd->filtertype, rad); - gausstabcent= gausstab+rad; - - bigstep = pix*imgx; - for (x = 0; x < imgx; x++) { - float *srcd= work->rect + pix*x; - - dest = new->rect + pix*x; - - for (y = 0; y < imgy ; y++) { - int minr= y-rad<0?-y:-rad; - int maxr= y+rad>imgy?imgy-y:rad; - - src= srcd + bigstep*(y+minr); - - sum= gval = rval= bval= aval= 0.0f; - for (i= minr; i < maxr; i++) { - val= gausstabcent[i]; - sum+= val; - rval += val * src[0]; - if(pix==4) { - gval += val * src[1]; - bval += val * src[2]; - aval += val * src[3]; - } - src += bigstep; - } - sum= 1.0f/sum; - dest[0] = rval*sum; - if(pix==4) { - dest[1] = gval*sum; - dest[2] = bval*sum; - dest[3] = aval*sum; - } - dest+= bigstep; - } - } - - free_compbuf(work); - MEM_freeT(gausstab); + CompBuf *work; + register float sum, val; + float rval, gval, bval, aval; + float *gausstab, *gausstabcent; + int rad, imgx= img->x, imgy= img->y; + int x, y, pix= img->type; + int i, bigstep; + float *src, *dest; + + /* helper image */ + work= alloc_compbuf(imgx, imgy, img->type, 1); // allocs + + /* horizontal */ + rad = scale*(float)nbd->sizex; + if(rad>imgx/2) + rad= imgx/2; + else if(rad<1) + rad= 1; + + gausstab= make_gausstab(nbd->filtertype, rad); + gausstabcent= gausstab+rad; + + for (y = 0; y < imgy; y++) { + float *srcd= img->rect + pix*(y*img->x); + + dest = work->rect + pix*(y * img->x); + + for (x = 0; x < imgx ; x++) { + int minr= x-rad<0?-x:-rad; + int maxr= x+rad>imgx?imgx-x:rad; + + src= srcd + pix*(x+minr); + + sum= gval = rval= bval= aval= 0.0f; + for (i= minr; i < maxr; i++) { + val= gausstabcent[i]; + sum+= val; + rval += val * (*src++); + if(pix==4) { + gval += val * (*src++); + bval += val * (*src++); + aval += val * (*src++); + } + } + sum= 1.0f/sum; + *dest++ = rval*sum; + if(pix==4) { + *dest++ = gval*sum; + *dest++ = bval*sum; + *dest++ = aval*sum; + } + } + } + + /* vertical */ + MEM_freeT(gausstab); + + rad = scale*(float)nbd->sizey; + if(rad>imgy/2) + rad= imgy/2; + else if(rad<1) + rad= 1; + + gausstab= make_gausstab(nbd->filtertype, rad); + gausstabcent= gausstab+rad; + + bigstep = pix*imgx; + for (x = 0; x < imgx; x++) { + float *srcd= work->rect + pix*x; + + dest = new->rect + pix*x; + + for (y = 0; y < imgy ; y++) { + int minr= y-rad<0?-y:-rad; + int maxr= y+rad>imgy?imgy-y:rad; + + src= srcd + bigstep*(y+minr); + + sum= gval = rval= bval= aval= 0.0f; + for (i= minr; i < maxr; i++) { + val= gausstabcent[i]; + sum+= val; + rval += val * src[0]; + if(pix==4) { + gval += val * src[1]; + bval += val * src[2]; + aval += val * src[3]; + } + src += bigstep; + } + sum= 1.0f/sum; + dest[0] = rval*sum; + if(pix==4) { + dest[1] = gval*sum; + dest[2] = bval*sum; + dest[3] = aval*sum; + } + dest+= bigstep; + } + } + + free_compbuf(work); + MEM_freeT(gausstab); } /* reference has to be mapped 0-1, and equal in size */ static void bloom_with_reference(CompBuf *new, CompBuf *img, CompBuf *ref, float fac, NodeBlurData *nbd) { - CompBuf *wbuf; - register float val; - float radxf, radyf; - float **maintabs; - float *gausstabx, *gausstabcenty; - float *gausstaby, *gausstabcentx; - int radx, rady, imgx= img->x, imgy= img->y; - int x, y; - int i, j; - float *src, *dest, *wb; - - wbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1); - - /* horizontal */ - radx = (float)nbd->sizex; - if(radx>imgx/2) - radx= imgx/2; - else if(radx<1) - radx= 1; - - /* vertical */ - rady = (float)nbd->sizey; - if(rady>imgy/2) - rady= imgy/2; - else if(rady<1) - rady= 1; - - x= MAX2(radx, rady); - maintabs= MEM_mallocT(x*sizeof(void *), "gauss array"); - for(i= 0; irect; - src= img->rect; - - radxf= (float)radx; - radyf= (float)rady; - - for (y = 0; y < imgy; y++) { - for (x = 0; x < imgx ; x++, src+=4) {//, refd++) { - -// int refradx= (int)(refd[0]*radxf); -// int refrady= (int)(refd[0]*radyf); - - int refradx= (int)(radxf*0.3f*src[3]*(src[0]+src[1]+src[2])); - int refrady= (int)(radyf*0.3f*src[3]*(src[0]+src[1]+src[2])); - - if(refradx>radx) refradx= radx; - else if(refradx<1) refradx= 1; - if(refrady>rady) refrady= rady; - else if(refrady<1) refrady= 1; - - if(refradx==1 && refrady==1) { - wb= wbuf->rect + ( y*imgx + x); - dest= new->rect + 4*( y*imgx + x); - wb[0]+= 1.0f; - dest[0] += src[0]; - dest[1] += src[1]; - dest[2] += src[2]; - dest[3] += src[3]; - } - else { - int minxr= x-refradx<0?-x:-refradx; - int maxxr= x+refradx>imgx?imgx-x:refradx; - int minyr= y-refrady<0?-y:-refrady; - int maxyr= y+refrady>imgy?imgy-y:refrady; - - float *destd= new->rect + 4*( (y + minyr)*imgx + x + minxr); - float *wbufd= wbuf->rect + ( (y + minyr)*imgx + x + minxr); - - gausstabx= maintabs[refradx-1]; - gausstabcentx= gausstabx+refradx; - gausstaby= maintabs[refrady-1]; - gausstabcenty= gausstaby+refrady; - - for (i= minyr; i < maxyr; i++, destd+= 4*imgx, wbufd+= imgx) { - dest= destd; - wb= wbufd; - for (j= minxr; j < maxxr; j++, dest+=4, wb++) { - - val= gausstabcenty[i]*gausstabcentx[j]; - wb[0]+= val; - dest[0] += val * src[0]; - dest[1] += val * src[1]; - dest[2] += val * src[2]; - dest[3] += val * src[3]; - } - } - } - } - } - - x= imgx*imgy; - dest= new->rect; - wb= wbuf->rect; - while(x--) { - val= 1.0f/wb[0]; - dest[0]*= val; - dest[1]*= val; - dest[2]*= val; - dest[3]*= val; - wb++; - dest+= 4; - } - - free_compbuf(wbuf); - - x= MAX2(radx, rady); - for(i= 0; ix, imgy= img->y; + int x, y; + int i, j; + float *src, *dest, *wb; + + wbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1); + + /* horizontal */ + radx = (float)nbd->sizex; + if(radx>imgx/2) + radx= imgx/2; + else if(radx<1) + radx= 1; + + /* vertical */ + rady = (float)nbd->sizey; + if(rady>imgy/2) + rady= imgy/2; + else if(rady<1) + rady= 1; + + x= MAX2(radx, rady); + maintabs= MEM_mallocT(x*sizeof(void *), "gauss array"); + for(i= 0; irect; + src= img->rect; + + radxf= (float)radx; + radyf= (float)rady; + + for (y = 0; y < imgy; y++) { + for (x = 0; x < imgx ; x++, src+=4) {//, refd++) { + + // int refradx= (int)(refd[0]*radxf); + // int refrady= (int)(refd[0]*radyf); + + int refradx= (int)(radxf*0.3f*src[3]*(src[0]+src[1]+src[2])); + int refrady= (int)(radyf*0.3f*src[3]*(src[0]+src[1]+src[2])); + + if(refradx>radx) refradx= radx; + else if(refradx<1) refradx= 1; + if(refrady>rady) refrady= rady; + else if(refrady<1) refrady= 1; + + if(refradx==1 && refrady==1) { + wb= wbuf->rect + ( y*imgx + x); + dest= new->rect + 4*( y*imgx + x); + wb[0]+= 1.0f; + dest[0] += src[0]; + dest[1] += src[1]; + dest[2] += src[2]; + dest[3] += src[3]; + } + else { + int minxr= x-refradx<0?-x:-refradx; + int maxxr= x+refradx>imgx?imgx-x:refradx; + int minyr= y-refrady<0?-y:-refrady; + int maxyr= y+refrady>imgy?imgy-y:refrady; + + float *destd= new->rect + 4*( (y + minyr)*imgx + x + minxr); + float *wbufd= wbuf->rect + ( (y + minyr)*imgx + x + minxr); + + gausstabx= maintabs[refradx-1]; + gausstabcentx= gausstabx+refradx; + gausstaby= maintabs[refrady-1]; + gausstabcenty= gausstaby+refrady; + + for (i= minyr; i < maxyr; i++, destd+= 4*imgx, wbufd+= imgx) { + dest= destd; + wb= wbufd; + for (j= minxr; j < maxxr; j++, dest+=4, wb++) { + + val= gausstabcenty[i]*gausstabcentx[j]; + wb[0]+= val; + dest[0] += val * src[0]; + dest[1] += val * src[1]; + dest[2] += val * src[2]; + dest[3] += val * src[3]; + } + } + } + } + } + + x= imgx*imgy; + dest= new->rect; + wb= wbuf->rect; + while(x--) { + val= 1.0f/wb[0]; + dest[0]*= val; + dest[1]*= val; + dest[2]*= val; + dest[3]*= val; + wb++; + dest+= 4; + } + + free_compbuf(wbuf); + + x= MAX2(radx, rady); + for(i= 0; itype!=CB_RGBA) return; - - drect= img->rect; - if(inversed) { - for(x=img->x*img->y; x>0; x--, drect+=4) { - if(drect[0]>0.0f) drect[0]= sqrt(drect[0]); else drect[0]= 0.0f; - if(drect[1]>0.0f) drect[1]= sqrt(drect[1]); else drect[1]= 0.0f; - if(drect[2]>0.0f) drect[2]= sqrt(drect[2]); else drect[2]= 0.0f; - } - } - else { - for(x=img->x*img->y; x>0; x--, drect+=4) { - if(drect[0]>0.0f) drect[0]*= drect[0]; else drect[0]= 0.0f; - if(drect[1]>0.0f) drect[1]*= drect[1]; else drect[1]= 0.0f; - if(drect[2]>0.0f) drect[2]*= drect[2]; else drect[2]= 0.0f; - } - } + float *drect; + int x; + + if(img->type!=CB_RGBA) return; + + drect= img->rect; + if(inversed) { + for(x=img->x*img->y; x>0; x--, drect+=4) { + if(drect[0]>0.0f) drect[0]= sqrt(drect[0]); else drect[0]= 0.0f; + if(drect[1]>0.0f) drect[1]= sqrt(drect[1]); else drect[1]= 0.0f; + if(drect[2]>0.0f) drect[2]= sqrt(drect[2]); else drect[2]= 0.0f; + } + } + else { + for(x=img->x*img->y; x>0; x--, drect+=4) { + if(drect[0]>0.0f) drect[0]*= drect[0]; else drect[0]= 0.0f; + if(drect[1]>0.0f) drect[1]*= drect[1]; else drect[1]= 0.0f; + if(drect[2]>0.0f) drect[2]*= drect[2]; else drect[2]= 0.0f; + } + } } #if 0 static float hexagon_filter(float fi, float fj) { - fi= fabs(fi); - fj= fabs(fj); - - if(fj>0.33f) { - fj= (fj-0.33f)/0.66f; - if(fi+fj>1.0f) - return 0.0f; - else - return 1.0f; - } - else return 1.0f; + fi= fabs(fi); + fj= fabs(fj); + + if(fj>0.33f) { + fj= (fj-0.33f)/0.66f; + if(fi+fj>1.0f) + return 0.0f; + else + return 1.0f; + } + else return 1.0f; } #endif @@ -2505,417 +2729,1022 @@ /* both images same type, either 1 or 4 channels */ static void bokeh_single_image(CompBuf *new, CompBuf *img, float fac, NodeBlurData *nbd) { - register float val; - float radxf, radyf; - float *gausstab, *dgauss; - int radx, rady, imgx= img->x, imgy= img->y; - int x, y, pix= img->type; - int i, j, n; - float *src= NULL, *dest, *srcd= NULL; - - /* horizontal */ - radxf = fac*(float)nbd->sizex; - if(radxf>imgx/2.0f) - radxf= imgx/2.0f; - else if(radxf<1.0f) - radxf= 1.0f; - - /* vertical */ - radyf = fac*(float)nbd->sizey; - if(radyf>imgy/2.0f) - radyf= imgy/2.0f; - else if(radyf<1.0f) - radyf= 1.0f; - - radx= ceil(radxf); - rady= ceil(radyf); - - n = (2*radx+1)*(2*rady+1); - - /* create a full filter image */ - gausstab= MEM_mallocT(sizeof(float)*n, "filter tab"); - dgauss= gausstab; - val= 0.0f; - for(j=-rady; j<=rady; j++) { - for(i=-radx; i<=radx; i++, dgauss++) { - float fj= (float)j/radyf; - float fi= (float)i/radxf; - float dist= sqrt(fj*fj + fi*fi); - -// *dgauss= hexagon_filter(fi, fj); - *dgauss= RE_filter_value(nbd->filtertype, 2.0f*dist - 1.0f); - - val+= *dgauss; - } - } - - if(val!=0.0f) { - val= 1.0f/val; - for(j= n -1; j>=0; j--) - gausstab[j]*= val; - } - else gausstab[4]= 1.0f; - - for (y = -rady+1; y < imgy+rady-1; y++) { - - if(y<=0) srcd= img->rect; - else if(yrect + pix*(imgy-1)*imgx; - - for (x = -radx+1; x < imgx+radx-1 ; x++) { - int minxr= x-radx<0?-x:-radx; - int maxxr= x+radx>=imgx?imgx-x-1:radx; - int minyr= y-rady<0?-y:-rady; - int maxyr= y+rady>imgy-1?imgy-y-1:rady; - - float *destd= new->rect + pix*( (y + minyr)*imgx + x + minxr); - float *dgausd= gausstab + (minyr+rady)*2*radx + minxr+radx; - - if(x<=0) src= srcd; - else if(x1) { - dest[1] += val * src[1]; - dest[2] += val * src[2]; - dest[3] += val * src[3]; - } - } - } - } - } - } - - MEM_freeT(gausstab); + register float val; + float radxf, radyf; + float *gausstab, *dgauss; + int radx, rady, imgx= img->x, imgy= img->y; + int x, y, pix= img->type; + int i, j, n; + float *src= NULL, *dest, *srcd= NULL; + + /* horizontal */ + radxf = fac*(float)nbd->sizex; + if(radxf>imgx/2.0f) + radxf= imgx/2.0f; + else if(radxf<1.0f) + radxf= 1.0f; + + /* vertical */ + radyf = fac*(float)nbd->sizey; + if(radyf>imgy/2.0f) + radyf= imgy/2.0f; + else if(radyf<1.0f) + radyf= 1.0f; + + radx= ceil(radxf); + rady= ceil(radyf); + + n = (2*radx+1)*(2*rady+1); + + /* create a full filter image */ + gausstab= MEM_mallocT(sizeof(float)*n, "filter tab"); + dgauss= gausstab; + val= 0.0f; + for(j=-rady; j<=rady; j++) { + for(i=-radx; i<=radx; i++, dgauss++) { + float fj= (float)j/radyf; + float fi= (float)i/radxf; + float dist= sqrt(fj*fj + fi*fi); + + // *dgauss= hexagon_filter(fi, fj); + *dgauss= RE_filter_value(nbd->filtertype, 2.0f*dist - 1.0f); + + val+= *dgauss; + } + } + + if(val!=0.0f) { + val= 1.0f/val; + for(j= n -1; j>=0; j--) + gausstab[j]*= val; + } + else gausstab[4]= 1.0f; + + for (y = -rady+1; y < imgy+rady-1; y++) { + + if(y<=0) srcd= img->rect; + else if(yrect + pix*(imgy-1)*imgx; + + for (x = -radx+1; x < imgx+radx-1 ; x++) { + int minxr= x-radx<0?-x:-radx; + int maxxr= x+radx>=imgx?imgx-x-1:radx; + int minyr= y-rady<0?-y:-rady; + int maxyr= y+rady>imgy-1?imgy-y-1:rady; + + float *destd= new->rect + pix*( (y + minyr)*imgx + x + minxr); + float *dgausd= gausstab + (minyr+rady)*2*radx + minxr+radx; + + if(x<=0) src= srcd; + else if(x1) { + dest[1] += val * src[1]; + dest[2] += val * src[2]; + dest[3] += val * src[3]; + } + } + } + } + } + } + + MEM_freeT(gausstab); } /* reference has to be mapped 0-1, and equal in size */ static void blur_with_reference(CompBuf *new, CompBuf *img, CompBuf *ref, NodeBlurData *nbd) { - CompBuf *blurbuf, *ref_use; - register float sum, val; - float rval, gval, bval, aval, radxf, radyf; - float **maintabs; - float *gausstabx, *gausstabcenty; - float *gausstaby, *gausstabcentx; - int radx, rady, imgx= img->x, imgy= img->y; - int x, y, pix= img->type; - int i, j; - float *src, *dest, *refd, *blurd; - - if(ref->x!=img->x && ref->y!=img->y) - return; - - ref_use= typecheck_compbuf(ref, CB_VAL); - - /* trick is; we blur the reference image... but only works with clipped values*/ - blurbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1); - blurd= blurbuf->rect; - refd= ref_use->rect; - for(x= imgx*imgy; x>0; x--, refd++, blurd++) { - if(refd[0]<0.0f) blurd[0]= 0.0f; - else if(refd[0]>1.0f) blurd[0]= 1.0f; - else blurd[0]= refd[0]; - } - - blur_single_image(blurbuf, blurbuf, 1.0f, nbd); - - /* horizontal */ - radx = (float)nbd->sizex; - if(radx>imgx/2) - radx= imgx/2; - else if(radx<1) - radx= 1; - - /* vertical */ - rady = (float)nbd->sizey; - if(rady>imgy/2) - rady= imgy/2; - else if(rady<1) - rady= 1; - - x= MAX2(radx, rady); - maintabs= MEM_mallocT(x*sizeof(void *), "gauss array"); - for(i= 0; ifiltertype, i+1); - - refd= blurbuf->rect; - dest= new->rect; - radxf= (float)radx; - radyf= (float)rady; - - for (y = 0; y < imgy; y++) { - for (x = 0; x < imgx ; x++, dest+=pix, refd++) { - int refradx= (int)(refd[0]*radxf); - int refrady= (int)(refd[0]*radyf); - - if(refradx>radx) refradx= radx; - else if(refradx<1) refradx= 1; - if(refrady>rady) refrady= rady; - else if(refrady<1) refrady= 1; - - if(refradx==1 && refrady==1) { - src= img->rect + pix*( y*imgx + x); - if(pix==1) - dest[0]= src[0]; - else - QUATCOPY(dest, src); - } - else { - int minxr= x-refradx<0?-x:-refradx; - int maxxr= x+refradx>imgx?imgx-x:refradx; - int minyr= y-refrady<0?-y:-refrady; - int maxyr= y+refrady>imgy?imgy-y:refrady; - - float *srcd= img->rect + pix*( (y + minyr)*imgx + x + minxr); - - gausstabx= maintabs[refradx-1]; - gausstabcentx= gausstabx+refradx; - gausstaby= maintabs[refrady-1]; - gausstabcenty= gausstaby+refrady; - - sum= gval = rval= bval= aval= 0.0f; - - for (i= minyr; i < maxyr; i++, srcd+= pix*imgx) { - src= srcd; - for (j= minxr; j < maxxr; j++, src+=pix) { - - val= gausstabcenty[i]*gausstabcentx[j]; - sum+= val; - rval += val * src[0]; - if(pix>1) { - gval += val * src[1]; - bval += val * src[2]; - aval += val * src[3]; - } - } - } - sum= 1.0f/sum; - dest[0] = rval*sum; - if(pix>1) { - dest[1] = gval*sum; - dest[2] = bval*sum; - dest[3] = aval*sum; - } - } - } - } - - free_compbuf(blurbuf); - - x= MAX2(radx, rady); - for(i= 0; ix, imgy= img->y; + int x, y, pix= img->type; + int i, j; + float *src, *dest, *refd, *blurd; + + if(ref->x!=img->x && ref->y!=img->y) + return; + + ref_use= typecheck_compbuf(ref, CB_VAL); + + /* trick is; we blur the reference image... but only works with clipped values*/ + blurbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1); + blurd= blurbuf->rect; + refd= ref_use->rect; + for(x= imgx*imgy; x>0; x--, refd++, blurd++) { + if(refd[0]<0.0f) blurd[0]= 0.0f; + else if(refd[0]>1.0f) blurd[0]= 1.0f; + else blurd[0]= refd[0]; + } + + blur_single_image(blurbuf, blurbuf, 1.0f, nbd); + + /* horizontal */ + radx = (float)nbd->sizex; + if(radx>imgx/2) + radx= imgx/2; + else if(radx<1) + radx= 1; + + /* vertical */ + rady = (float)nbd->sizey; + if(rady>imgy/2) + rady= imgy/2; + else if(rady<1) + rady= 1; + + x= MAX2(radx, rady); + maintabs= MEM_mallocT(x*sizeof(void *), "gauss array"); + for(i= 0; ifiltertype, i+1); + + refd= blurbuf->rect; + dest= new->rect; + radxf= (float)radx; + radyf= (float)rady; + + for (y = 0; y < imgy; y++) { + for (x = 0; x < imgx ; x++, dest+=pix, refd++) { + int refradx= (int)(refd[0]*radxf); + int refrady= (int)(refd[0]*radyf); + + if(refradx>radx) refradx= radx; + else if(refradx<1) refradx= 1; + if(refrady>rady) refrady= rady; + else if(refrady<1) refrady= 1; + + if(refradx==1 && refrady==1) { + src= img->rect + pix*( y*imgx + x); + if(pix==1) + dest[0]= src[0]; + else + QUATCOPY(dest, src); + } + else { + int minxr= x-refradx<0?-x:-refradx; + int maxxr= x+refradx>imgx?imgx-x:refradx; + int minyr= y-refrady<0?-y:-refrady; + int maxyr= y+refrady>imgy?imgy-y:refrady; + + float *srcd= img->rect + pix*( (y + minyr)*imgx + x + minxr); + + gausstabx= maintabs[refradx-1]; + gausstabcentx= gausstabx+refradx; + gausstaby= maintabs[refrady-1]; + gausstabcenty= gausstaby+refrady; + + sum= gval = rval= bval= aval= 0.0f; + + for (i= minyr; i < maxyr; i++, srcd+= pix*imgx) { + src= srcd; + for (j= minxr; j < maxxr; j++, src+=pix) { + + val= gausstabcenty[i]*gausstabcentx[j]; + sum+= val; + rval += val * src[0]; + if(pix>1) { + gval += val * src[1]; + bval += val * src[2]; + aval += val * src[3]; + } + } + } + sum= 1.0f/sum; + dest[0] = rval*sum; + if(pix>1) { + dest[1] = gval*sum; + dest[2] = bval*sum; + dest[3] = aval*sum; + } + } + } + } + + free_compbuf(blurbuf); + + x= MAX2(radx, rady); + for(i= 0; idata; - - if(img==NULL || img->type==CB_VEC3 || out[0]->hasoutput==0) - return; - - /* if fac input, we do it different */ - if(in[1]->data) { - - /* make output size of input image */ - new= alloc_compbuf(img->x, img->y, img->type, 1); // allocs - - blur_with_reference(new, img, in[1]->data, node->storage); - - out[0]->data= new; - } - else { - - if(in[1]->vec[0]==0.0f) { - /* pass on image */ - new= pass_on_compbuf(img); - } - else { - NodeBlurData *nbd= node->storage; - CompBuf *gammabuf; - - /* make output size of input image */ - new= alloc_compbuf(img->x, img->y, img->type, 1); // allocs - - if(nbd->gamma) { - gammabuf= dupalloc_compbuf(img); - gamma_correct_compbuf(gammabuf, 0); - } - else gammabuf= img; - - if(nbd->bokeh) - bokeh_single_image(new, gammabuf, in[1]->vec[0], nbd); - else if(1) - blur_single_image(new, gammabuf, in[1]->vec[0], nbd); - else /* bloom experimental... */ - bloom_with_reference(new, gammabuf, NULL, in[1]->vec[0], nbd); - - if(nbd->gamma) { - gamma_correct_compbuf(new, 1); - free_compbuf(gammabuf); - } - } - out[0]->data= new; - } + CompBuf *new, *img= in[0]->data; + + if(img==NULL || img->type==CB_VEC3 || out[0]->hasoutput==0) + return; + + /* if fac input, we do it different */ + if(in[1]->data) { + + /* make output size of input image */ + new= alloc_compbuf(img->x, img->y, img->type, 1); // allocs + + blur_with_reference(new, img, in[1]->data, node->storage); + + out[0]->data= new; + } + else { + + if(in[1]->vec[0]==0.0f) { + /* pass on image */ + new= pass_on_compbuf(img); + } + else { + NodeBlurData *nbd= node->storage; + CompBuf *gammabuf; + + /* make output size of input image */ + new= alloc_compbuf(img->x, img->y, img->type, 1); // allocs + + if(nbd->gamma) { + gammabuf= dupalloc_compbuf(img); + gamma_correct_compbuf(gammabuf, 0); + } + else gammabuf= img; + + if(nbd->bokeh) + bokeh_single_image(new, gammabuf, in[1]->vec[0], nbd); + else if(1) + blur_single_image(new, gammabuf, in[1]->vec[0], nbd); + else /* bloom experimental... */ + bloom_with_reference(new, gammabuf, NULL, in[1]->vec[0], nbd); + + if(nbd->gamma) { + gamma_correct_compbuf(new, 1); + free_compbuf(gammabuf); + } + } + out[0]->data= new; + } } - + static bNodeType cmp_node_blur= { - /* type code */ CMP_NODE_BLUR, - /* name */ "Blur", - /* width+range */ 120, 80, 200, - /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS, - /* input sock */ cmp_node_blur_in, - /* output sock */ cmp_node_blur_out, - /* storage */ "NodeBlurData", - /* execfunc */ node_composit_exec_blur - + /* type code */ CMP_NODE_BLUR, + /* name */ "Blur", + /* width+range */ 120, 80, 200, + /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS, + /* input sock */ cmp_node_blur_in, + /* output sock */ cmp_node_blur_out, + /* storage */ "NodeBlurData", + /* execfunc */ node_composit_exec_blur + }; /* **************** VECTOR BLUR ******************** */ static bNodeSocketType cmp_node_vecblur_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Z", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 1, "Speed", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Z", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, "Speed", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_vecblur_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void node_composit_exec_vecblur(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - NodeBlurData *nbd= node->storage; - CompBuf *new, *img= in[0]->data, *vecbuf= in[2]->data, *zbuf= in[1]->data; - - if(img==NULL || vecbuf==NULL || zbuf==NULL || out[0]->hasoutput==0) - return; - if(vecbuf->x!=img->x || vecbuf->y!=img->y) { - printf("ERROR: cannot do different sized vecbuf yet\n"); - return; - } - if(vecbuf->type!=CB_VEC4) { - printf("ERROR: input should be vecbuf\n"); - return; - } - if(zbuf->type!=CB_VAL) { - printf("ERROR: input should be zbuf\n"); - return; - } - if(zbuf->x!=img->x || zbuf->y!=img->y) { - printf("ERROR: cannot do different sized zbuf yet\n"); - return; - } - - new= dupalloc_compbuf(img); - - /* call special zbuffer version */ - RE_zbuf_accumulate_vecblur(nbd, img->x, img->y, new->rect, img->rect, vecbuf->rect, zbuf->rect); - - out[0]->data= new; + NodeBlurData *nbd= node->storage; + CompBuf *new, *img= in[0]->data, *vecbuf= in[2]->data, *zbuf= in[1]->data; + + if(img==NULL || vecbuf==NULL || zbuf==NULL || out[0]->hasoutput==0) + return; + if(vecbuf->x!=img->x || vecbuf->y!=img->y) { + printf("ERROR: cannot do different sized vecbuf yet\n"); + return; + } + if(vecbuf->type!=CB_VEC4) { + printf("ERROR: input should be vecbuf\n"); + return; + } + if(zbuf->type!=CB_VAL) { + printf("ERROR: input should be zbuf\n"); + return; + } + if(zbuf->x!=img->x || zbuf->y!=img->y) { + printf("ERROR: cannot do different sized zbuf yet\n"); + return; + } + + new= dupalloc_compbuf(img); + + /* call special zbuffer version */ + RE_zbuf_accumulate_vecblur(nbd, img->x, img->y, new->rect, img->rect, vecbuf->rect, zbuf->rect); + + out[0]->data= new; } /* custom1: itterations, custom2: maxspeed (0 = nolimit) */ static bNodeType cmp_node_vecblur= { - /* type code */ CMP_NODE_VECBLUR, - /* name */ "Vector Blur", - /* width+range */ 120, 80, 200, - /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS, - /* input sock */ cmp_node_vecblur_in, - /* output sock */ cmp_node_vecblur_out, - /* storage */ "NodeBlurData", - /* execfunc */ node_composit_exec_vecblur - + /* type code */ CMP_NODE_VECBLUR, + /* name */ "Vector Blur", + /* width+range */ 120, 80, 200, + /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS, + /* input sock */ cmp_node_vecblur_in, + /* output sock */ cmp_node_vecblur_out, + /* storage */ "NodeBlurData", + /* execfunc */ node_composit_exec_vecblur + }; /* **************** Translate ******************** */ static bNodeSocketType cmp_node_translate_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 0, "X", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, - { SOCK_VALUE, 0, "Y", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, - { -1, 0, "" } + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "X", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + { SOCK_VALUE, 0, "Y", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + { -1, 0, "" } }; static bNodeSocketType cmp_node_translate_out[]= { - { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { -1, 0, "" } + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } }; static void node_composit_exec_translate(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - if(in[0]->data) { - CompBuf *cbuf= in[0]->data; - CompBuf *stackbuf= pass_on_compbuf(cbuf); // no alloc - - stackbuf->xof= (int)floor(in[1]->vec[0]); - stackbuf->yof= (int)floor(in[2]->vec[0]); - - stackbuf->rect= cbuf->rect; - out[0]->data= stackbuf; - } + if(in[0]->data) { + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= pass_on_compbuf(cbuf); // no alloc + + stackbuf->xof= (int)floor(in[1]->vec[0]); + stackbuf->yof= (int)floor(in[2]->vec[0]); + + stackbuf->rect= cbuf->rect; + out[0]->data= stackbuf; + } } static bNodeType cmp_node_translate= { - /* type code */ CMP_NODE_TRANSLATE, - /* name */ "Translate", - /* width+range */ 140, 100, 320, - /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS, - /* input sock */ cmp_node_translate_in, - /* output sock */ cmp_node_translate_out, - /* storage */ "", - /* execfunc */ node_composit_exec_translate + /* type code */ CMP_NODE_TRANSLATE, + /* name */ "Translate", + /* width+range */ 140, 100, 320, + /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS, + /* input sock */ cmp_node_translate_in, + /* output sock */ cmp_node_translate_out, + /* storage */ "", + /* execfunc */ node_composit_exec_translate +}; + +/* ******************* YUV Difference Matte ********************************* */ +static bNodeSocketType cmp_node_YUV_matte_in[]={ + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {SOCK_RGBA,1,"Key", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {-1,0,""}, +}; + +static bNodeSocketType cmp_node_YUV_matte_out[]={ + {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + {-1,0,""} +}; + +static void node_composit_exec_YUV_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + int i,max; + + float tolerance; + float yuvkey[3]; + NodeChroma *c; + CompBuf *yuvbuf; + CompBuf *rgbbuf; + CompBuf *matte; + CompBuf *cbuf; + + if(out[0]->hasoutput==0 || in[0]->hasinput==0) return; + if(in[0]->data==NULL) return; + + cbuf=in[0]->data; + + //is it an RGBA image or a value + if(cbuf->type==CB_RGBA) + { + c=node->storage; + tolerance=c->rt; + yuvbuf=alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA,1); + rgbbuf=dupalloc_compbuf(cbuf); + matte=alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA,1); + + //convert RGB to YUV + max=cbuf->x*cbuf->y*4; + for(i=0;irect[i+0],cbuf->rect[i+1],cbuf->rect[i+2],&yuvbuf->rect[i+0], &yuvbuf->rect[i+1], &yuvbuf->rect[i+2]); + yuvbuf->rect[3]=cbuf->rect[3]; + } + + //convert key to YUV + rgb_to_yuv(in[1]->vec[0], in[1]->vec[1], in[1]->vec[2], &yuvkey[0], &yuvkey[1], &yuvkey[2]); + + for(i=0;irect[i+3]==0.0) + { + //premultiplied + rgbbuf->rect[i+3]=0.0; + //matte + matte->rect[i+0]=0.0; + matte->rect[i+1]=0.0; + matte->rect[i+2]=0.0; + matte->rect[i+3]=1.0; + } + + else if(sqrt((yuvkey[0]-yuvbuf->rect[i+0])*(yuvkey[0]-yuvbuf->rect[i+0])+ + (yuvkey[1]-yuvbuf->rect[i+1])*(yuvkey[1]-yuvbuf->rect[i+1])+ + (yuvkey[2]-yuvbuf->rect[i+2])*(yuvkey[2]-yuvbuf->rect[i+2]))rect[i+3]=0.0; + //matte + matte->rect[i+0]=0.0; + matte->rect[i+1]=0.0; + matte->rect[i+2]=0.0; + matte->rect[i+3]=1.0; + + } + else + { + //premultipled + rgbbuf->rect[i+3]=1.0; + //matte + matte->rect[i+0]=1.0; + matte->rect[i+1]=1.0; + matte->rect[i+2]=1.0; + matte->rect[i+3]=1.0; + } + } + + //free the yuv image + free_compbuf(yuvbuf); + + out[0]->data=rgbbuf; + out[1]->data=matte; + + generate_preview(node, rgbbuf); + } + else + { + return; + } +} + +static bNodeType cmp_node_YUV_matte={ + /* type code */ CMP_NODE_YUV_MATTE, + /* name */ "YUV Difference Matte", + /* width+range */ 200, 80, 250, + /* class+opts */ NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS, + /* input sock */ cmp_node_YUV_matte_in, + /* output sock */ cmp_node_YUV_matte_out, + /* storage */ "NodeChroma", + /* execfunc */ node_composit_exec_YUV_matte +}; + + +/* ******************* RGB Difference Matte ********************************* */ +static bNodeSocketType cmp_node_diff_matte_in[]={ + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {-1,0,""} +}; + +static bNodeSocketType cmp_node_diff_matte_out[]={ + {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + {-1,0,""} +}; + +static void node_composit_exec_diff_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + int i,max; + int use_val=0; + + CompBuf *rgbbuf; + CompBuf *matte; + CompBuf *cbuf1, *cbuf2; + NodeChroma *c; + float tolerance; + + //is anything connected? + if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return; + //must have an image imput + if(in[0]->data==NULL) return; + //using an image or a color? + if(in[1]->data==NULL) use_val=1; + + if(use_val==0) + { + cbuf1=in[0]->data; + cbuf2=in[1]->data; + //same size? + if(cbuf1->x!=cbuf2->x || cbuf1->y!=cbuf2->y) return; + + c=node->storage; + rgbbuf=dupalloc_compbuf(cbuf1); + matte=alloc_compbuf(cbuf1->x, cbuf1->y,CB_RGBA,1); + + //find min/max tolerances + tolerance=c->rt; + max=cbuf1->x*cbuf1->y*4; + + for(i=0;irect[i+3]==0.0) + { + //premultiplied + rgbbuf->rect[i+3]=0.0; + //matte + matte->rect[i+0]=0.0; + matte->rect[i+1]=0.0; + matte->rect[i+2]=0.0; + matte->rect[i+3]=1.0; + } + + //new way (distance in 3 space between colors) + else if(sqrt((cbuf2->rect[i+0]-cbuf1->rect[i+0])*(cbuf2->rect[i+0]-cbuf1->rect[i+0])+ + (cbuf2->rect[i+1]-cbuf1->rect[i+1])*(cbuf2->rect[i+1]-cbuf1->rect[i+1])+ + (cbuf2->rect[i+2]-cbuf1->rect[i+2])*(cbuf2->rect[i+2]-cbuf1->rect[i+2]))rect[i+3]=0.0; + //rgbbuf->rect[i+3]=1-(g) + //matte + matte->rect[i+0]=0.0; + matte->rect[i+1]=0.0; + matte->rect[i+2]=0.0; + matte->rect[i+3]=1.0; + + } + else + { + //premultipled + rgbbuf->rect[i+3]=1.0; + //matte + matte->rect[i+0]=1.0; + matte->rect[i+1]=1.0; + matte->rect[i+2]=1.0; + matte->rect[i+3]=1.0; + } + } + } + //use the input color + else + { + cbuf1=in[0]->data; + c=node->storage; + + rgbbuf=dupalloc_compbuf(cbuf1); + matte=alloc_compbuf(cbuf1->x, cbuf1->y,CB_RGBA,1); + tolerance=c->rt; + + max=cbuf1->x*cbuf1->y*4; + + for(i=0;irect[i+3]==0) + { + //make transparent + //premultiplied + rgbbuf->rect[i+3]=0.0; + //matte + matte->rect[i+0]=0.0; + matte->rect[i+1]=0.0; + matte->rect[i+2]=0.0; + matte->rect[i+3]=1.0; + } + else if(sqrt((in[1]->vec[0]-cbuf1->rect[i+0])*(in[1]->vec[0]-cbuf1->rect[i+0])+ + (in[1]->vec[1]-cbuf1->rect[i+1])*(in[1]->vec[1]-cbuf1->rect[i+1])+ + (in[1]->vec[2]-cbuf1->rect[i+2])*(in[1]->vec[2]-cbuf1->rect[i+2]))rect[i+3]=0.0; + //matte + matte->rect[i+0]=0.0; + matte->rect[i+1]=0.0; + matte->rect[i+2]=0.0; + matte->rect[i+3]=1.0; + } + else + { + //foreground object + //premultipled + rgbbuf->rect[i+3]=1.0; + //matte + matte->rect[i+0]=1.0; + matte->rect[i+1]=1.0; + matte->rect[i+2]=1.0; + matte->rect[i+3]=1.0; + } + } + } + out[0]->data=rgbbuf; + out[1]->data=matte; + generate_preview(node, rgbbuf); +} + +static bNodeType cmp_node_diff_matte={ + /* type code */ CMP_NODE_DIFF_MATTE, + /* name */ "RGB Difference Matte", + /* width+range */ 200, 80, 250, + /* class+opts */ NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS, + /* input sock */ cmp_node_diff_matte_in, + /* output sock */ cmp_node_diff_matte_out, + /* storage */ "NodeChroma", + /* execfunc */ node_composit_exec_diff_matte +}; + +/* ******************* Chroma Matte ********************************* */ +static bNodeSocketType cmp_node_chroma_matte_in[]={ + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {SOCK_RGBA,1,"Key", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {-1,0,""} +}; + +static bNodeSocketType cmp_node_chroma_matte_out[]={ + {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + {-1,0,""} +}; + + +static void node_composit_exec_chroma_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + int i,max; + + float tolerance; + float ycckey[3]; + CompBuf *cbuf; + NodeChroma *c; + CompBuf *yccbuf; + CompBuf *rgbbuf; + CompBuf *matte; + + if(out[0]->hasoutput==0 || in[0]->hasinput==0) return; + if(in[0]->data==NULL) return; + + cbuf=in[0]->data; + + //is it an RGBA image or a value + if(cbuf->type==CB_RGBA) + { + c=node->storage; + tolerance=c->rt; + yccbuf=alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA,1); + rgbbuf=dupalloc_compbuf(cbuf); + matte=alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA,1); + + //convert RGB to YCC + max=cbuf->x*cbuf->y*4; + for(i=0;irect[i+0],cbuf->rect[i+1],cbuf->rect[i+2],&yccbuf->rect[i+0], &yccbuf->rect[i+1], &yccbuf->rect[i+2]); + yccbuf->rect[3]=cbuf->rect[3]; + } + + //convert key to YCC + rgb_to_ycc(in[1]->vec[0], in[1]->vec[1], in[1]->vec[2], &ycckey[0], &ycckey[1], &ycckey[2]); + + for(i=0;irect[i+3]==0.0) + { + //premultiplied + rgbbuf->rect[i+3]=0.0; + //matte + matte->rect[i+0]=0.0; + matte->rect[i+1]=0.0; + matte->rect[i+2]=0.0; + matte->rect[i+3]=1.0; + } + else if(sqrt((ycckey[0]-yccbuf->rect[i+0])*(ycckey[0]-yccbuf->rect[i+0])+ + (ycckey[1]-yccbuf->rect[i+1])*(ycckey[1]-yccbuf->rect[i+1])+ + (ycckey[2]-yccbuf->rect[i+2])*(ycckey[2]-yccbuf->rect[i+2]))rect[i+3]=0.0; + //matte + matte->rect[i+0]=0.0; + matte->rect[i+1]=0.0; + matte->rect[i+2]=0.0; + matte->rect[i+3]=1.0; + + } + else //the pixel is not masked + { + //premultipled + rgbbuf->rect[i+3]=1.0; + //matte + matte->rect[i+0]=1.0; + matte->rect[i+1]=1.0; + matte->rect[i+2]=1.0; + matte->rect[i+3]=1.0; + } + } + + //free the ycc image + free_compbuf(yccbuf); + + out[0]->data=rgbbuf; + out[1]->data=matte; + + generate_preview(node, rgbbuf); + } + else + { + return; + } +} + +static bNodeType cmp_node_chroma_matte={ + /* type code */ CMP_NODE_CHROMA_MATTE, + /* name */ "Chroma Difference Matte", + /* width+range */ 200, 80, 250, + /* class+opts */ NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS, + /* input sock */ cmp_node_chroma_matte_in, + /* output sock */ cmp_node_chroma_matte_out, + /* storage */ "NodeChroma", + /* execfunc */ node_composit_exec_chroma_matte +}; + + +/* ******************* Color Spill Supression ********************************* */ +static bNodeSocketType cmp_node_color_spill_in[]={ + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {-1,0,""} +}; + +static bNodeSocketType cmp_node_color_spill_out[]={ + {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {-1,0,""} +}; + + +static void node_composit_exec_color_spill(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + int i,max; + float tolerance; + CompBuf *cbuf; + CompBuf *rgbbuf; + NodeChroma *c; + + if(out[0]->hasoutput==0 || in[0]->hasinput==0) return; + if(in[0]->data==NULL) return; + + cbuf=in[0]->data; + c=node->storage; + tolerance=c->rt; + + //is it an RGBA image + if(cbuf->type==CB_RGBA) + { + rgbbuf=dupalloc_compbuf(cbuf); + max=cbuf->x*cbuf->y*4; + + switch(node->custom1) + { + case 1: //red spill + { + for(i=0;irect[i+0]>cbuf->rect[i+2]) + { + rgbbuf->rect[i+0]=rgbbuf->rect[i+2]-(tolerance*rgbbuf->rect[i+2]); + } + } + break; + } + case 2: //green spill + { + for(i=0;irect[i+1]>cbuf->rect[i+2]) + { + rgbbuf->rect[i+1]=rgbbuf->rect[i+2]-(tolerance*rgbbuf->rect[i+2]); + } + } + break; + } + case 3: //blue spill + { + for(i=0;irect[i+2]>cbuf->rect[i+1]) + { + rgbbuf->rect[i+2]=rgbbuf->rect[i+1]-(tolerance*rgbbuf->rect[i+1]); + } + } + break; + } + default: + break; + } + + out[0]->data=rgbbuf; + } + else + { + return; + } +} + +static bNodeType cmp_node_color_spill={ + /* type code */ CMP_NODE_COLOR_SPILL, + /* name */ "Color Spill", + /* width+range */ 140, 80, 140, + /* class+opts */ NODE_CLASS_MATTE, NODE_OPTIONS, + /* input sock */ cmp_node_color_spill_in, + /* output sock */ cmp_node_color_spill_out, + /* storage */ "NodeChroma", + /* execfunc */ node_composit_exec_color_spill +}; + +/* **************** Dilate/Erode ******************** */ + +static bNodeSocketType cmp_node_dilateerode_in[]= { + { SOCK_VALUE, 1, "Mask", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType cmp_node_dilateerode_out[]= { + { SOCK_VALUE, 0, "Mask", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void morpho_dilate(CompBuf *cbuf) +{ + int x, y; + float *p, *rectf = cbuf->rect; + + for (y=0; y < cbuf->y; y++) { + for (x=0; x < cbuf->x-1; x++) { + p = rectf + cbuf->x*y + x; + *p = MAX2(*p, *(p + 1)); + } + } + + for (y=0; y < cbuf->y; y++) { + for (x=cbuf->x-1; x >= 1; x--) { + p = rectf + cbuf->x*y + x; + *p = MAX2(*p, *(p - 1)); + } + } + + for (x=0; x < cbuf->x; x++) { + for (y=0; y < cbuf->y-1; y++) { + p = rectf + cbuf->x*y + x; + *p = MAX2(*p, *(p + cbuf->x)); + } + } + + for (x=0; x < cbuf->x; x++) { + for (y=cbuf->y-1; y >= 1; y--) { + p = rectf + cbuf->x*y + x; + *p = MAX2(*p, *(p - cbuf->x)); + } + } +} + +static void morpho_erode(CompBuf *cbuf) +{ + int x, y; + float *p, *rectf = cbuf->rect; + + for (y=0; y < cbuf->y; y++) { + for (x=0; x < cbuf->x-1; x++) { + p = rectf + cbuf->x*y + x; + *p = MIN2(*p, *(p + 1)); + } + } + + for (y=0; y < cbuf->y; y++) { + for (x=cbuf->x-1; x >= 1; x--) { + p = rectf + cbuf->x*y + x; + *p = MIN2(*p, *(p - 1)); + } + } + + for (x=0; x < cbuf->x; x++) { + for (y=0; y < cbuf->y-1; y++) { + p = rectf + cbuf->x*y + x; + *p = MIN2(*p, *(p + cbuf->x)); + } + } + + for (x=0; x < cbuf->x; x++) { + for (y=cbuf->y-1; y >= 1; y--) { + p = rectf + cbuf->x*y + x; + *p = MIN2(*p, *(p - cbuf->x)); + } + } + +} + +static void node_composit_exec_dilateerode(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order in: mask */ + /* stack order out: mask */ + if(out[0]->hasoutput==0) + return; + + /* input no image? then only color operation */ + if(in[0]->data==NULL) { + out[0]->vec[0] = out[0]->vec[1] = out[0]->vec[2] = 0.0f; + out[0]->vec[3] = 0.0f; + } + else { + /* make output size of input image */ + CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_VAL); + CompBuf *stackbuf= dupalloc_compbuf(cbuf); + short i; + + if (node->custom2 > 0) { // positive, dilate + for (i = 0; i < node->custom2; i++) + morpho_dilate(stackbuf); + } else if (node->custom2 < 0) { // negative, erode + for (i = 0; i > node->custom2; i--) + morpho_erode(stackbuf); + } + + out[0]->data= stackbuf; + } +} + +static bNodeType cmp_node_dilateerode= { + /* type code */ CMP_NODE_DILATE_ERODE, + /* name */ "Dilate/Erode", + /* width+range */ 130, 100, 320, + /* class+opts */ NODE_CLASS_MATTE, NODE_OPTIONS, + /* input sock */ cmp_node_dilateerode_in, + /* output sock */ cmp_node_dilateerode_out, + /* storage */ "", + /* execfunc */ node_composit_exec_dilateerode }; + /* ****************** types array for all shaders ****************** */ bNodeType *node_all_composit[]= { - &node_group_typeinfo, - &cmp_node_composite, - &cmp_node_viewer, - &cmp_node_output_file, - &cmp_node_rlayers, - &cmp_node_image, - &cmp_node_curve_rgb, - &cmp_node_mix_rgb, - &cmp_node_hue_sat, - &cmp_node_alphaover, - &cmp_node_value, - &cmp_node_rgb, - &cmp_node_normal, - &cmp_node_curve_vec, - &cmp_node_time, - &cmp_node_filter, - &cmp_node_blur, - &cmp_node_vecblur, - &cmp_node_map_value, - &cmp_node_valtorgb, - &cmp_node_rgbtobw, - &cmp_node_seprgba, - &cmp_node_sephsva, - &cmp_node_setalpha, - &cmp_node_texture, - &cmp_node_translate, - &cmp_node_zcombine, - NULL + &node_group_typeinfo, + &cmp_node_composite, + &cmp_node_viewer, + &cmp_node_output_file, + &cmp_node_rlayers, + &cmp_node_image, + &cmp_node_curve_rgb, + &cmp_node_mix_rgb, + &cmp_node_hue_sat, + &cmp_node_alphaover, + &cmp_node_value, + &cmp_node_rgb, + &cmp_node_normal, + &cmp_node_curve_vec, + &cmp_node_time, + &cmp_node_filter, + &cmp_node_blur, + &cmp_node_vecblur, + &cmp_node_map_value, + &cmp_node_valtorgb, + &cmp_node_rgbtobw, + &cmp_node_seprgba, + &cmp_node_sephsva, + &cmp_node_sepyuva, + &cmp_node_setalpha, + &cmp_node_texture, + &cmp_node_translate, + &cmp_node_zcombine, + &cmp_node_YUV_matte, + &cmp_node_diff_matte, + &cmp_node_chroma_matte, + &cmp_node_color_spill, + &cmp_node_sepycca, + &cmp_node_combrgba, + &cmp_node_dilateerode, + NULL }; /* ******************* parse ************ */ @@ -2924,46 +3753,46 @@ /* called from render pipeline, to tag render input and output */ void ntreeCompositTagRender(bNodeTree *ntree) { - bNode *node; - - if(ntree==NULL) return; - - for(node= ntree->nodes.first; node; node= node->next) { - if( ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE)) - NodeTagChanged(ntree, node); - } + bNode *node; + + if(ntree==NULL) return; + + for(node= ntree->nodes.first; node; node= node->next) { + if( ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE)) + NodeTagChanged(ntree, node); + } } /* tags nodes that have animation capabilities */ void ntreeCompositTagAnimated(bNodeTree *ntree) { - bNode *node; - - if(ntree==NULL) return; - - for(node= ntree->nodes.first; node; node= node->next) { - if(node->type==CMP_NODE_IMAGE) { - /* no actual test yet... */ - if(node->storage) - NodeTagChanged(ntree, node); - } - else if(node->type==CMP_NODE_TIME) - NodeTagChanged(ntree, node); - } + bNode *node; + + if(ntree==NULL) return; + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->type==CMP_NODE_IMAGE) { + /* no actual test yet... */ + if(node->storage) + NodeTagChanged(ntree, node); + } + else if(node->type==CMP_NODE_TIME) + NodeTagChanged(ntree, node); + } } /* called from image window preview */ void ntreeCompositTagGenerators(bNodeTree *ntree) { - bNode *node; - - if(ntree==NULL) return; - - for(node= ntree->nodes.first; node; node= node->next) { - if( ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_IMAGE)) - NodeTagChanged(ntree, node); - } + bNode *node; + + if(ntree==NULL) return; + + for(node= ntree->nodes.first; node; node= node->next) { + if( ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_IMAGE)) + NodeTagChanged(ntree, node); + } } diff -Naur blender2.42/source/blender/blenlib/BLI_arithb.h blender-work/source/blender/blenlib/BLI_arithb.h --- blender2.42/source/blender/blenlib/BLI_arithb.h 2006-06-03 13:21:45.000000000 -0400 +++ blender-work/source/blender/blenlib/BLI_arithb.h 2006-07-17 21:12:44.000000000 -0400 @@ -666,7 +666,13 @@ void hex_to_rgb(char *hexcol, float *r, float *g, float *b); - void +void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv); +void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb); + +void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb); +void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr); + +void rgb_to_hsv( float r, float g, float b, float *lh, float *ls, float *lv diff -Naur blender2.42/source/blender/blenlib/intern/arithb.c blender-work/source/blender/blenlib/intern/arithb.c --- blender2.42/source/blender/blenlib/intern/arithb.c 2006-07-05 00:03:40.000000000 -0400 +++ blender-work/source/blender/blenlib/intern/arithb.c 2006-07-18 13:10:55.000000000 -0400 @@ -2639,6 +2639,61 @@ } } +void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv) +{ + float y, u, v; + y= 0.299*r + 0.587*g + 0.114*b; + u=-0.147*r - 0.289*g + 0.436*b; + v= 0.615*r - 0.515*g - 0.100*b; + + *ly=y; + *lu=u; + *lv=v; +} + +void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb) +{ + float r, g, b; + r=y+1.140*v; + g=y-0.394*u - 0.581*v; + b=y+2.032*u; + + *lr=r; + *lg=g; + *lb=b; +} + +void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr) +{ + float sr,sg, sb; + float y, cr, cb; + + sr=255.0*r; + sg=255.0*g; + sb=255.0*b; + + //y-16, cb-128, cr-128 + y=(0.257*sr)+(0.504*sg)+(0.098*sb)+16.0; + cb=(-0.148*sr)-(0.291*sg)+(0.439*sb)+128.0; + cr=(0.439*sr)-(0.368*sg)-(0.071*sb)+128.0; + + *ly=y; + *lcb=cb; + *lcr=cr; +} + +void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb) +{ + float r,g,b; + + r=1.164*(y-16)+1.596*(cr-128); + g=1.164*(y-16)-0.813*(cr-128)-0.392*(cb-128); + b=1.164*(y-16)+2.017*(cb-128); + + *lr=r/255.0; + *lg=g/255.0; + *lb=b/255.0; +} void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv) { float h, s, v; diff -Naur blender2.42/source/blender/makesdna/DNA_node_types.h blender-work/source/blender/makesdna/DNA_node_types.h --- blender2.42/source/blender/makesdna/DNA_node_types.h 2006-06-17 09:04:09.000000000 -0400 +++ blender-work/source/blender/makesdna/DNA_node_types.h 2006-07-19 00:50:40.000000000 -0400 @@ -90,11 +90,10 @@ /* only used now for groups... */ #define SOCK_IN_USE 4 -# -# typedef struct bNodePreview { float *rect; short xsize, ysize; + int pad; } bNodePreview; @@ -193,8 +192,12 @@ } NodeBlurData; typedef struct NodeHueSat { - float hue, sat; + float hue, sat,val; } NodeHueSat; +typedef struct NodeChroma { + float rt, gt, bt; +} NodeChroma; + #endif diff -Naur blender2.42/source/blender/src/drawnode.c blender-work/source/blender/src/drawnode.c --- blender2.42/source/blender/src/drawnode.c 2006-07-03 05:49:12.000000000 -0400 +++ blender-work/source/blender/src/drawnode.c 2006-07-19 00:01:56.000000000 -0400 @@ -975,16 +975,96 @@ NodeHueSat *nhs= node->storage; uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Hue ", - butr->xmin, butr->ymin+19.0f, butr->xmax-butr->xmin, 19, - &nhs->hue, 0.0f, 1.0f, 100, 0, ""); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Sat ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, - &nhs->sat, 0.0f, 2.0f, 100, 0, ""); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Hue: ", + butr->xmin, butr->ymin+40.0f, butr->xmax-butr->xmin, 20, + &nhs->hue, 0.0f, 1.0f, 100, 0, ""); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Sat: ", + butr->xmin, butr->ymin+20.0f, butr->xmax-butr->xmin, 20, + &nhs->sat, 0.0f, 2.0f, 100, 0, ""); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Val: ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &nhs->val, 0.0f, 2.0f, 100, 0, ""); + } + return 60; +} + +static int node_composit_buts_YUV_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) + { + NodeChroma *c= node->storage; + uiBlockBeginAlign(block); + + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, + &c->rt, 0.0f, 1.0f, 100, 0, ""); + } + return 19; +} + +static int node_composit_buts_diff_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) + { + NodeChroma *c= node->storage; + uiBlockBeginAlign(block); + + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, + &c->rt, 0.0f, 1.0f, 100, 0, ""); + } + return 19; +} + +static int node_composit_buts_chroma_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) + { + NodeChroma *c= node->storage; + uiBlockBeginAlign(block); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, + &c->rt, 0.0f, 255.0f, 100, 0, ""); + } + return 19; +} + +static int node_composit_buts_color_spill(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) + { + short dx= (butr->xmax-butr->xmin)/3; + + NodeChroma *c=node->storage; + uiBlockBeginAlign(block); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Enhancement ", + butr->xmin, butr->ymin+19.0, butr->xmax-butr->xmin, 19, + &c->rt, 0.0f, 0.5f, 100, 0, ""); + uiDefButS(block, ROW,B_DIFF,"R", + butr->xmin,butr->ymin,dx,19, + &node->custom1,1,1, 0, 0, "Red Spill Suppression"); + uiDefButS(block, ROW,B_DIFF,"G", + butr->xmin+dx,butr->ymin,dx,19, + &node->custom1,1,2, 0, 0, "Green Spill Suppression"); + uiDefButS(block, ROW,B_DIFF,"B", + butr->xmin+2*dx,butr->ymin,dx,19, + &node->custom1,1,3, 0, 0, "Blue Spill Suppression"); + uiBlockEndAlign(block); } return 38; } +static int node_composit_buts_dilateerode(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Distance:", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &node->custom2, -100, 100, 0, 0, "Distance to grow/shrink (number of iterations)"); + } + return 20; +} + + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) @@ -1044,6 +1124,21 @@ case CMP_NODE_TEXTURE: ntype->butfunc= node_buts_texture; break; + case CMP_NODE_YUV_MATTE: + ntype->butfunc=node_composit_buts_YUV_matte; + break; + case CMP_NODE_DIFF_MATTE: + ntype->butfunc=node_composit_buts_diff_matte; + break; + case CMP_NODE_CHROMA_MATTE: + ntype->butfunc=node_composit_buts_chroma_matte; + break; + case CMP_NODE_COLOR_SPILL: + ntype->butfunc=node_composit_buts_color_spill; + break; + case CMP_NODE_DILATE_ERODE: + ntype->butfunc= node_composit_buts_dilateerode; + break; default: ntype->butfunc= NULL; } diff -Naur blender2.42/source/blender/src/header_node.c blender-work/source/blender/src/header_node.c --- blender2.42/source/blender/src/header_node.c 2006-06-26 07:01:09.000000000 -0400 +++ blender-work/source/blender/src/header_node.c 2006-07-17 13:01:37.000000000 -0400 @@ -368,6 +368,19 @@ return block; } +static uiBlock *node_add_mattemenu(void *arg_unused) +{ + SpaceNode *snode=curarea->spacedata.first; + uiBlock *block; + + block=uiNewBlock(&curarea->uiblocks, "node_add_mattemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetButmFunc(block,do_node_addmenu, NULL); + node_make_addmenu(snode, NODE_CLASS_MATTE, block); + uiBlockSetDirection(block, UI_RIGHT); + uiTextBoundsBlock(block,60); + return block; +} + static uiBlock *node_addmenu(void *arg_unused) { SpaceNode *snode= curarea->spacedata.first; @@ -394,6 +407,7 @@ uiDefIconTextBlockBut(block, node_add_filtermenu, NULL, ICON_RIGHTARROW_THIN, "Filter", 0, yco-=20, 120, 19, ""); uiDefIconTextBlockBut(block, node_add_convertermenu, NULL, ICON_RIGHTARROW_THIN, "Convertor", 0, yco-=20, 120, 19, ""); uiDefIconTextBlockBut(block, node_add_groupmenu, NULL, ICON_RIGHTARROW_THIN, "Group", 0, yco-=20, 120, 19, ""); + uiDefIconTextBlockBut(block, node_add_mattemenu, NULL, ICON_RIGHTARROW_THIN, "Matte", 0, yco-=20, 120,19,""); } else uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); diff -Naur blender2.42/source/blender/src/toolbox.c blender-work/source/blender/src/toolbox.c --- blender2.42/source/blender/src/toolbox.c 2006-07-12 10:51:30.000000000 -0400 +++ blender-work/source/blender/src/toolbox.c 2006-07-18 15:50:37.000000000 -0400 @@ -1526,6 +1526,7 @@ #define TB_CMP_OP_FILTER 4 #define TB_CMP_CONVERTORS 5 #define TB_CMP_GROUPS 6 +#define TB_CMP_MATTE 7 static TBitem tb_node_addcomp[]= { { 0, "Input", 1, NULL}, @@ -1535,6 +1536,7 @@ { 0, "Filters", 5, NULL}, { 0, "Convertors", 6, NULL}, { 0, "Groups", 7, NULL}, + { 0, "Mattes", 8, NULL}, { -1, "", 0, NULL}}; /* do_node_addmenu() in header_node.c, prototype in BSE_headerbuttons.h */ @@ -1738,6 +1740,7 @@ TBitem *menu7=NULL, *groupmenu= NULL; TBitem *node_add_gen= NULL, *node_add_group= NULL, *node_add_out= NULL, *node_add_in= NULL; TBitem *node_add_op_col= NULL, *node_add_op_filt= NULL, *node_add_op_vec= NULL, *node_add_con= NULL; + TBitem *node_add_matte=NULL; int dx=0; short event, mval[2], tot=0; char *str1=NULL, *str2=NULL, *str3=NULL, *str4=NULL, *str5=NULL, *str6=NULL, *str7=NULL; @@ -1918,6 +1921,7 @@ node_add_op_vec= node_add_sublevel(&menu1[TB_CMP_OP_VECTOR].poin, snode->nodetree, NODE_CLASS_OP_VECTOR); node_add_con= node_add_sublevel(&menu1[TB_CMP_CONVERTORS].poin, snode->nodetree, NODE_CLASS_CONVERTOR); node_add_group= node_add_sublevel(&menu1[TB_CMP_GROUPS].poin, snode->nodetree, NODE_CLASS_GROUP); + node_add_matte= node_add_sublevel(&menu1[TB_CMP_MATTE].poin,snode->nodetree, NODE_CLASS_MATTE); } dx= 96; @@ -2018,7 +2022,8 @@ if(node_add_con) MEM_freeN(node_add_con); if(node_add_gen) MEM_freeN(node_add_gen); if(node_add_group) MEM_freeN(node_add_group); - + if(node_add_matte) MEM_freeN(node_add_matte); + mywinset(curarea->win); }