|
Blender
V2.59
|
00001 /* 00002 * $Id: CMP_filter.c 35237 2011-02-27 20:13:22Z jesterking $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2006 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include "../CMP_util.h" 00036 00037 /* **************** FILTER ******************** */ 00038 static bNodeSocketType cmp_node_filter_in[]= { 00039 { SOCK_VALUE, 1, "Fac", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, 00040 { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, 00041 { -1, 0, "" } 00042 }; 00043 static bNodeSocketType cmp_node_filter_out[]= { 00044 { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 00045 { -1, 0, "" } 00046 }; 00047 00048 static void do_filter_edge(CompBuf *out, CompBuf *in, float *filter, float fac) 00049 { 00050 float *row1, *row2, *row3; 00051 float *fp, f1, f2, mfac= 1.0f-fac; 00052 int rowlen, x, y, c, pix= in->type; 00053 00054 rowlen= in->x; 00055 00056 for(y=0; y<in->y; y++) { 00057 /* setup rows */ 00058 if(y==0) row1= in->rect; 00059 else row1= in->rect + pix*(y-1)*rowlen; 00060 00061 row2= in->rect + y*pix*rowlen; 00062 00063 if(y==in->y-1) row3= row2; 00064 else row3= row2 + pix*rowlen; 00065 00066 fp= out->rect + pix*y*rowlen; 00067 00068 if(pix==CB_RGBA) { 00069 QUATCOPY(fp, row2); 00070 fp+= pix; 00071 00072 for(x=2; x<rowlen; x++) { 00073 for(c=0; c<3; c++) { 00074 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]; 00075 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]; 00076 fp[0]= mfac*row2[4] + fac*sqrt(f1*f1 + f2*f2); 00077 fp++; row1++; row2++; row3++; 00078 } 00079 fp[0]= row2[4]; 00080 /* no alpha... will clear it completely */ 00081 fp++; row1++; row2++; row3++; 00082 } 00083 QUATCOPY(fp, row2+4); 00084 } 00085 else if(pix==CB_VAL) { 00086 fp+= pix; 00087 for(x=2; x<rowlen; x++) { 00088 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]; 00089 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]; 00090 fp[0]= mfac*row2[1] + fac*sqrt(f1*f1 + f2*f2); 00091 fp++; row1++; row2++; row3++; 00092 } 00093 } 00094 } 00095 } 00096 00097 static void do_filter3(CompBuf *out, CompBuf *in, float *filter, float fac) 00098 { 00099 float *row1, *row2, *row3; 00100 float *fp, mfac= 1.0f-fac; 00101 int rowlen, x, y, c; 00102 int pixlen= in->type; 00103 00104 rowlen= in->x; 00105 00106 for(y=0; y<in->y; y++) { 00107 /* setup rows */ 00108 if(y==0) row1= in->rect; 00109 else row1= in->rect + pixlen*(y-1)*rowlen; 00110 00111 row2= in->rect + y*pixlen*rowlen; 00112 00113 if(y==in->y-1) row3= row2; 00114 else row3= row2 + pixlen*rowlen; 00115 00116 fp= out->rect + pixlen*(y)*rowlen; 00117 00118 if(pixlen==1) { 00119 fp[0]= row2[0]; 00120 fp+= 1; 00121 00122 for(x=2; x<rowlen; x++) { 00123 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]); 00124 fp++; row1++; row2++; row3++; 00125 } 00126 fp[0]= row2[1]; 00127 } 00128 else if(pixlen==2) { 00129 fp[0]= row2[0]; 00130 fp[1]= row2[1]; 00131 fp+= 2; 00132 00133 for(x=2; x<rowlen; x++) { 00134 for(c=0; c<2; c++) { 00135 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]); 00136 fp++; row1++; row2++; row3++; 00137 } 00138 } 00139 fp[0]= row2[2]; 00140 fp[1]= row2[3]; 00141 } 00142 else if(pixlen==3) { 00143 VECCOPY(fp, row2); 00144 fp+= 3; 00145 00146 for(x=2; x<rowlen; x++) { 00147 for(c=0; c<3; c++) { 00148 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]); 00149 fp++; row1++; row2++; row3++; 00150 } 00151 } 00152 VECCOPY(fp, row2+3); 00153 } 00154 else { 00155 QUATCOPY(fp, row2); 00156 fp+= 4; 00157 00158 for(x=2; x<rowlen; x++) { 00159 for(c=0; c<4; c++) { 00160 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]); 00161 fp++; row1++; row2++; row3++; 00162 } 00163 } 00164 QUATCOPY(fp, row2+4); 00165 } 00166 } 00167 } 00168 00169 00170 static void node_composit_exec_filter(void *data, bNode *node, bNodeStack **in, bNodeStack **out) 00171 { 00172 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}; 00173 float sharp[9]= {-1,-1,-1,-1,9,-1,-1,-1,-1}; 00174 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}; 00175 float sobel[9]= {1,2,1,0,0,0,-1,-2,-1}; 00176 float prewitt[9]= {1,1,1,0,0,0,-1,-1,-1}; 00177 float kirsch[9]= {5,5,5,-3,-3,-3,-2,-2,-2}; 00178 float shadow[9]= {1,2,1,0,1,0,-1,-2,-1}; 00179 00180 if(out[0]->hasoutput==0) return; 00181 00182 /* stack order in: Image */ 00183 /* stack order out: Image */ 00184 00185 if(in[1]->data) { 00186 /* make output size of first available input image */ 00187 CompBuf *cbuf= in[1]->data; 00188 CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1); /* allocs */ 00189 00190 /* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */ 00191 stackbuf->xof= cbuf->xof; 00192 stackbuf->yof= cbuf->yof; 00193 00194 switch(node->custom1) { 00195 case CMP_FILT_SOFT: 00196 do_filter3(stackbuf, cbuf, soft, in[0]->vec[0]); 00197 break; 00198 case CMP_FILT_SHARP: 00199 do_filter3(stackbuf, cbuf, sharp, in[0]->vec[0]); 00200 break; 00201 case CMP_FILT_LAPLACE: 00202 do_filter3(stackbuf, cbuf, laplace, in[0]->vec[0]); 00203 break; 00204 case CMP_FILT_SOBEL: 00205 do_filter_edge(stackbuf, cbuf, sobel, in[0]->vec[0]); 00206 break; 00207 case CMP_FILT_PREWITT: 00208 do_filter_edge(stackbuf, cbuf, prewitt, in[0]->vec[0]); 00209 break; 00210 case CMP_FILT_KIRSCH: 00211 do_filter_edge(stackbuf, cbuf, kirsch, in[0]->vec[0]); 00212 break; 00213 case CMP_FILT_SHADOW: 00214 do_filter3(stackbuf, cbuf, shadow, in[0]->vec[0]); 00215 break; 00216 } 00217 00218 out[0]->data= stackbuf; 00219 00220 generate_preview(data, node, out[0]->data); 00221 } 00222 } 00223 00224 00225 void register_node_type_cmp_filter(ListBase *lb) 00226 { 00227 static bNodeType ntype; 00228 00229 node_type_base(&ntype, CMP_NODE_FILTER, "Filter", NODE_CLASS_OP_FILTER, NODE_PREVIEW|NODE_OPTIONS, 00230 cmp_node_filter_in, cmp_node_filter_out); 00231 node_type_size(&ntype, 80, 40, 120); 00232 node_type_label(&ntype, node_filter_label); 00233 node_type_exec(&ntype, node_composit_exec_filter); 00234 00235 nodeRegisterType(lb, &ntype); 00236 } 00237 00238 00239