/** * $Id$ * * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 "../CMP_util.h" /* **************** 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, "" } }; static bNodeSocketType cmp_node_filter_out[]= { { 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 + 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+= 1; 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 */ /* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */ stackbuf->xof= cbuf->xof; stackbuf->yof= cbuf->yof; 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; generate_preview(data, node, out[0]->data); } } bNodeType cmp_node_filter= { /* *next,*prev */ NULL, NULL, /* type code */ CMP_NODE_FILTER, /* name */ "Filter", /* width+range */ 80, 40, 120, /* class+opts */ NODE_CLASS_OP_FILTER, NODE_PREVIEW|NODE_OPTIONS, /* input sock */ cmp_node_filter_in, /* output sock */ cmp_node_filter_out, /* storage */ "", /* execfunc */ node_composit_exec_filter, /* butfunc */ NULL, /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, /* id */ NULL };