2
* $Id: CMP_filter.c 12931 2007-12-17 18:20:48Z theeth $
4
* ***** BEGIN GPL LICENSE BLOCK *****
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software Foundation,
18
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
* The Original Code is Copyright (C) 2006 Blender Foundation.
21
* All rights reserved.
23
* The Original Code is: all of this file.
25
* Contributor(s): none yet.
27
* ***** END GPL LICENSE BLOCK *****
30
#include "../CMP_util.h"
32
/* **************** FILTER ******************** */
33
static bNodeSocketType cmp_node_filter_in[]= {
34
{ SOCK_VALUE, 1, "Fac", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
35
{ SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
38
static bNodeSocketType cmp_node_filter_out[]= {
39
{ SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
43
static void do_filter_edge(CompBuf *out, CompBuf *in, float *filter, float fac)
45
float *row1, *row2, *row3;
46
float *fp, f1, f2, mfac= 1.0f-fac;
47
int rowlen, x, y, c, pix= in->type;
51
for(y=0; y<in->y; y++) {
53
if(y==0) row1= in->rect;
54
else row1= in->rect + pix*(y-1)*rowlen;
56
row2= in->rect + y*pix*rowlen;
58
if(y==in->y-1) row3= row2;
59
else row3= row2 + pix*rowlen;
61
fp= out->rect + pix*y*rowlen;
67
for(x=2; x<rowlen; x++) {
69
f1= filter[0]*row1[0] + filter[1]*row1[4] + filter[2]*row1[8] + filter[3]*row2[0] + filter[4]*row2[4] + filter[5]*row2[8] + filter[6]*row3[0] + filter[7]*row3[4] + filter[8]*row3[8];
70
f2= filter[0]*row1[0] + filter[3]*row1[4] + filter[6]*row1[8] + filter[1]*row2[0] + filter[4]*row2[4] + filter[7]*row2[8] + filter[2]*row3[0] + filter[5]*row3[4] + filter[8]*row3[8];
71
fp[0]= mfac*row2[4] + fac*sqrt(f1*f1 + f2*f2);
72
fp++; row1++; row2++; row3++;
75
/* no alpha... will clear it completely */
76
fp++; row1++; row2++; row3++;
80
else if(pix==CB_VAL) {
81
for(x=2; x<rowlen; x++) {
82
f1= filter[0]*row1[0] + filter[1]*row1[1] + filter[2]*row1[2] + filter[3]*row2[0] + filter[4]*row2[1] + filter[5]*row2[2] + filter[6]*row3[0] + filter[7]*row3[1] + filter[8]*row3[2];
83
f2= filter[0]*row1[0] + filter[3]*row1[1] + filter[6]*row1[2] + filter[1]*row2[0] + filter[4]*row2[1] + filter[7]*row2[2] + filter[2]*row3[0] + filter[5]*row3[1] + filter[8]*row3[2];
84
fp[0]= mfac*row2[1] + fac*sqrt(f1*f1 + f2*f2);
85
fp++; row1++; row2++; row3++;
91
static void do_filter3(CompBuf *out, CompBuf *in, float *filter, float fac)
93
float *row1, *row2, *row3;
94
float *fp, mfac= 1.0f-fac;
100
for(y=0; y<in->y; y++) {
102
if(y==0) row1= in->rect;
103
else row1= in->rect + pixlen*(y-1)*rowlen;
105
row2= in->rect + y*pixlen*rowlen;
107
if(y==in->y-1) row3= row2;
108
else row3= row2 + pixlen*rowlen;
110
fp= out->rect + pixlen*(y)*rowlen;
116
for(x=2; x<rowlen; x++) {
117
fp[0]= mfac*row2[1] + fac*(filter[0]*row1[0] + filter[1]*row1[1] + filter[2]*row1[2] + filter[3]*row2[0] + filter[4]*row2[1] + filter[5]*row2[2] + filter[6]*row3[0] + filter[7]*row3[1] + filter[8]*row3[2]);
118
fp++; row1++; row2++; row3++;
127
for(x=2; x<rowlen; x++) {
129
fp[0]= mfac*row2[2] + fac*(filter[0]*row1[0] + filter[1]*row1[2] + filter[2]*row1[4] + filter[3]*row2[0] + filter[4]*row2[2] + filter[5]*row2[4] + filter[6]*row3[0] + filter[7]*row3[2] + filter[8]*row3[4]);
130
fp++; row1++; row2++; row3++;
140
for(x=2; x<rowlen; x++) {
142
fp[0]= mfac*row2[3] + fac*(filter[0]*row1[0] + filter[1]*row1[3] + filter[2]*row1[6] + filter[3]*row2[0] + filter[4]*row2[3] + filter[5]*row2[6] + filter[6]*row3[0] + filter[7]*row3[3] + filter[8]*row3[6]);
143
fp++; row1++; row2++; row3++;
152
for(x=2; x<rowlen; x++) {
154
fp[0]= mfac*row2[4] + fac*(filter[0]*row1[0] + filter[1]*row1[4] + filter[2]*row1[8] + filter[3]*row2[0] + filter[4]*row2[4] + filter[5]*row2[8] + filter[6]*row3[0] + filter[7]*row3[4] + filter[8]*row3[8]);
155
fp++; row1++; row2++; row3++;
158
QUATCOPY(fp, row2+4);
164
static void node_composit_exec_filter(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
166
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};
167
float sharp[9]= {-1,-1,-1,-1,9,-1,-1,-1,-1};
168
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};
169
float sobel[9]= {1,2,1,0,0,0,-1,-2,-1};
170
float prewitt[9]= {1,1,1,0,0,0,-1,-1,-1};
171
float kirsch[9]= {5,5,5,-3,-3,-3,-2,-2,-2};
172
float shadow[9]= {1,2,1,0,1,0,-1,-2,-1};
174
if(out[0]->hasoutput==0) return;
176
/* stack order in: Image */
177
/* stack order out: Image */
180
/* make output size of first available input image */
181
CompBuf *cbuf= in[1]->data;
182
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1); /* allocs */
184
/* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */
185
stackbuf->xof= cbuf->xof;
186
stackbuf->yof= cbuf->yof;
188
switch(node->custom1) {
190
do_filter3(stackbuf, cbuf, soft, in[0]->vec[0]);
193
do_filter3(stackbuf, cbuf, sharp, in[0]->vec[0]);
195
case CMP_FILT_LAPLACE:
196
do_filter3(stackbuf, cbuf, laplace, in[0]->vec[0]);
199
do_filter_edge(stackbuf, cbuf, sobel, in[0]->vec[0]);
201
case CMP_FILT_PREWITT:
202
do_filter_edge(stackbuf, cbuf, prewitt, in[0]->vec[0]);
204
case CMP_FILT_KIRSCH:
205
do_filter_edge(stackbuf, cbuf, kirsch, in[0]->vec[0]);
207
case CMP_FILT_SHADOW:
208
do_filter3(stackbuf, cbuf, shadow, in[0]->vec[0]);
212
out[0]->data= stackbuf;
217
bNodeType cmp_node_filter= {
218
/* *next,*prev */ NULL, NULL,
219
/* type code */ CMP_NODE_FILTER,
221
/* width+range */ 80, 40, 120,
222
/* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS,
223
/* input sock */ cmp_node_filter_in,
224
/* output sock */ cmp_node_filter_out,
226
/* execfunc */ node_composit_exec_filter,
229
/* freestoragefunc */ NULL,
230
/* copystoragefunc */ NULL,