despeckle composite node
[blender.git] / source / blender / compositor / intern / COM_Converter.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor: 
19  *              Jeroen Bakker 
20  *              Monique Dewanchand
21  */
22
23 #include <string.h>
24
25 #include "BKE_node.h"
26
27 #include "COM_AlphaOverNode.h"
28 #include "COM_BilateralBlurNode.h"
29 #include "COM_BlurNode.h"
30 #include "COM_BokehBlurNode.h"
31 #include "COM_BokehImageNode.h"
32 #include "COM_BoxMaskNode.h"
33 #include "COM_BrightnessNode.h"
34 #include "COM_ChannelMatteNode.h"
35 #include "COM_ChromaMatteNode.h"
36 #include "COM_ColorBalanceNode.h"
37 #include "COM_ColorCorrectionNode.h"
38 #include "COM_ColorCurveNode.h"
39 #include "COM_ColorMatteNode.h"
40 #include "COM_ColorNode.h"
41 #include "COM_ColorRampNode.h"
42 #include "COM_ColorSpillNode.h"
43 #include "COM_ColorToBWNode.h"
44 #include "COM_CombineHSVANode.h"
45 #include "COM_CombineRGBANode.h"
46 #include "COM_CombineYCCANode.h"
47 #include "COM_CombineYUVANode.h"
48 #include "COM_CompositorNode.h"
49 #include "COM_ConvertAlphaNode.h"
50 #include "COM_ConvertColorToVectorOperation.h"
51 #include "COM_ConvertColorToValueProg.h"
52 #include "COM_ConvertValueToColorProg.h"
53 #include "COM_ConvertValueToVectorOperation.h"
54 #include "COM_ConvertVectorToColorOperation.h"
55 #include "COM_ConvertVectorToValueOperation.h"
56 #include "COM_Converter.h"
57 #include "COM_CropNode.h"
58 #include "COM_DefocusNode.h"
59 #include "COM_DespeckleNode.h"
60 #include "COM_DifferenceMatteNode.h"
61 #include "COM_DilateErodeNode.h"
62 #include "COM_DirectionalBlurNode.h"
63 #include "COM_DisplaceNode.h"
64 #include "COM_DistanceMatteNode.h"
65 #include "COM_DoubleEdgeMaskNode.h"
66 #include "COM_EllipseMaskNode.h"
67 #include "COM_ExecutionSystem.h"
68 #include "COM_ExecutionSystemHelper.h"
69 #include "COM_FilterNode.h"
70 #include "COM_FlipNode.h"
71 #include "COM_GammaNode.h"
72 #include "COM_GlareNode.h"
73 #include "COM_GroupNode.h"
74 #include "COM_HueSaturationValueCorrectNode.h"
75 #include "COM_HueSaturationValueNode.h"
76 #include "COM_IDMaskNode.h"
77 #include "COM_ImageNode.h"
78 #include "COM_InpaintNode.h"
79 #include "COM_InvertNode.h"
80 #include "COM_KeyingNode.h"
81 #include "COM_KeyingScreenNode.h"
82 #include "COM_LensDistortionNode.h"
83 #include "COM_LuminanceMatteNode.h"
84 #include "COM_MapUVNode.h"
85 #include "COM_MapValueNode.h"
86 #include "COM_MaskNode.h"
87 #include "COM_MathNode.h"
88 #include "COM_MixNode.h"
89 #include "COM_MovieClipNode.h"
90 #include "COM_MovieDistortionNode.h"
91 #include "COM_MuteNode.h"
92 #include "COM_NormalNode.h"
93 #include "COM_NormalizeNode.h"
94 #include "COM_OutputFileNode.h"
95 #include "COM_RenderLayersNode.h"
96 #include "COM_RotateNode.h"
97 #include "COM_ScaleNode.h"
98 #include "COM_ScaleOperation.h"
99 #include "COM_SeparateHSVANode.h"
100 #include "COM_SeparateRGBANode.h"
101 #include "COM_SeparateYCCANode.h"
102 #include "COM_SeparateYUVANode.h"
103 #include "COM_SetAlphaNode.h"
104 #include "COM_SetValueOperation.h"
105 #include "COM_SocketConnection.h"
106 #include "COM_SplitViewerNode.h"
107 #include "COM_Stabilize2dNode.h"
108 #include "COM_SwitchNode.h"
109 #include "COM_TextureNode.h"
110 #include "COM_TimeNode.h"
111 #include "COM_TonemapNode.h"
112 #include "COM_TransformNode.h"
113 #include "COM_TranslateNode.h"
114 #include "COM_TranslateOperation.h"
115 #include "COM_TrackPositionNode.h"
116 #include "COM_ValueNode.h"
117 #include "COM_VectorBlurNode.h"
118 #include "COM_VectorCurveNode.h"
119 #include "COM_ViewLevelsNode.h"
120 #include "COM_ViewerNode.h"
121 #include "COM_ZCombineNode.h"
122
123 Node *Converter::convert(bNode *b_node, bool fast)
124 {
125         Node *node;
126
127         if (b_node->flag & NODE_MUTED) {
128                 node = new MuteNode(b_node);
129                 return node;
130         }
131         if (fast) {
132                 if (b_node->type == CMP_NODE_BLUR ||
133                     b_node->type == CMP_NODE_VECBLUR ||
134                     b_node->type == CMP_NODE_BILATERALBLUR ||
135                     b_node->type == CMP_NODE_DEFOCUS ||
136                     b_node->type == CMP_NODE_BOKEHBLUR ||
137                     b_node->type == CMP_NODE_GLARE ||
138                     b_node->type == CMP_NODE_DBLUR ||
139                     b_node->type == CMP_NODE_MOVIEDISTORTION ||
140                     b_node->type == CMP_NODE_LENSDIST ||
141                     b_node->type == CMP_NODE_DOUBLEEDGEMASK ||
142                     b_node->type == CMP_NODE_DILATEERODE)
143                 {
144                         return new MuteNode(b_node);
145                 }
146         }
147
148         switch (b_node->type) {
149                 case CMP_NODE_COMPOSITE:
150                         node = new CompositorNode(b_node);
151                         break;
152                 case CMP_NODE_R_LAYERS:
153                         node = new RenderLayersNode(b_node);
154                         break;
155                 case CMP_NODE_TEXTURE:
156                         node = new TextureNode(b_node);
157                         break;
158                 case CMP_NODE_RGBTOBW:
159                         node = new ColorToBWNode(b_node);
160                         break;
161                 case CMP_NODE_MIX_RGB:
162                         node = new MixNode(b_node);
163                         break;
164                 case CMP_NODE_TRANSLATE:
165                         node = new TranslateNode(b_node);
166                         break;
167                 case CMP_NODE_SCALE:
168                         node = new ScaleNode(b_node);
169                         break;
170                 case CMP_NODE_ROTATE:
171                         node = new RotateNode(b_node);
172                         break;
173                 case CMP_NODE_FLIP:
174                         node = new FlipNode(b_node);
175                         break;
176                 case CMP_NODE_FILTER:
177                         node = new FilterNode(b_node);
178                         break;
179                 case CMP_NODE_ID_MASK:
180                         node = new IDMaskNode(b_node);
181                         break;
182                 case CMP_NODE_BRIGHTCONTRAST:
183                         node = new BrightnessNode(b_node);
184                         break;
185                 case CMP_NODE_SEPRGBA:
186                         node = new SeparateRGBANode(b_node);
187                         break;
188                 case CMP_NODE_COMBRGBA:
189                         node = new CombineRGBANode(b_node);
190                         break;
191                 case CMP_NODE_SEPHSVA:
192                         node = new SeparateHSVANode(b_node);
193                         break;
194                 case CMP_NODE_COMBHSVA:
195                         node = new CombineHSVANode(b_node);
196                         break;
197                 case CMP_NODE_SEPYUVA:
198                         node = new SeparateYUVANode(b_node);
199                         break;
200                 case CMP_NODE_COMBYUVA:
201                         node = new CombineYUVANode(b_node);
202                         break;
203                 case CMP_NODE_SEPYCCA:
204                         node = new SeparateYCCANode(b_node);
205                         break;
206                 case CMP_NODE_COMBYCCA:
207                         node = new CombineYCCANode(b_node);
208                         break;
209                 case CMP_NODE_ALPHAOVER:
210                         node = new AlphaOverNode(b_node);
211                         break;
212                 case CMP_NODE_COLORBALANCE:
213                         node = new ColorBalanceNode(b_node);
214                         break;
215                 case CMP_NODE_VIEWER:
216                         node = new ViewerNode(b_node);
217                         break;
218                 case CMP_NODE_SPLITVIEWER:
219                         node = new SplitViewerNode(b_node);
220                         break;
221                 case CMP_NODE_INVERT:
222                         node = new InvertNode(b_node);
223                         break;
224                 case NODE_GROUP:
225                         node = new GroupNode(b_node);
226                         break;
227                 case CMP_NODE_NORMAL:
228                         node = new NormalNode(b_node);
229                         break;
230                 case CMP_NODE_NORMALIZE:
231                         node = new NormalizeNode(b_node);
232                         break;
233                 case CMP_NODE_IMAGE:
234                         node = new ImageNode(b_node);
235                         break;
236                 case CMP_NODE_SETALPHA:
237                         node = new SetAlphaNode(b_node);
238                         break;
239                 case CMP_NODE_PREMULKEY:
240                         node = new ConvertAlphaNode(b_node);
241                         break;
242                 case CMP_NODE_MATH:
243                         node = new MathNode(b_node);
244                         break;
245                 case CMP_NODE_HUE_SAT:
246                         node = new HueSaturationValueNode(b_node);
247                         break;
248                 case CMP_NODE_COLORCORRECTION:
249                         node = new ColorCorrectionNode(b_node);
250                         break;
251                 case CMP_NODE_MASK_BOX:
252                         node = new BoxMaskNode(b_node);
253                         break;
254                 case CMP_NODE_MASK_ELLIPSE:
255                         node = new EllipseMaskNode(b_node);
256                         break;
257                 case CMP_NODE_GAMMA:
258                         node = new GammaNode(b_node);
259                         break;
260                 case CMP_NODE_CURVE_RGB:
261                         node = new ColorCurveNode(b_node);
262                         break;
263                 case CMP_NODE_CURVE_VEC:
264                         node = new VectorCurveNode(b_node);
265                         break;
266                 case CMP_NODE_HUECORRECT:
267                         node = new HueSaturationValueCorrectNode(b_node);
268                         break;
269                 case CMP_NODE_MAP_UV:
270                         node = new MapUVNode(b_node);
271                         break;
272                 case CMP_NODE_DISPLACE:
273                         node = new DisplaceNode(b_node);
274                         break;
275                 case CMP_NODE_VALTORGB:
276                         node = new ColorRampNode(b_node);
277                         break;
278                 case CMP_NODE_DIFF_MATTE:
279                         node = new DifferenceMatteNode(b_node);
280                         break;
281                 case CMP_NODE_LUMA_MATTE:
282                         node = new LuminanceMatteNode(b_node);
283                         break;
284                 case CMP_NODE_DIST_MATTE:
285                         node = new DistanceMatteNode(b_node);
286                         break;
287                 case CMP_NODE_CHROMA_MATTE:
288                         node = new ChromaMatteNode(b_node);
289                         break;
290                 case CMP_NODE_COLOR_MATTE:
291                         node = new ColorMatteNode(b_node);
292                         break;
293                 case CMP_NODE_CHANNEL_MATTE:
294                         node = new ChannelMatteNode(b_node);
295                         break;
296                 case CMP_NODE_BLUR:
297                         node = new BlurNode(b_node);
298                         break;
299                 case CMP_NODE_BOKEHIMAGE:
300                         node = new BokehImageNode(b_node);
301                         break;
302                 case CMP_NODE_BOKEHBLUR:
303                         node = new BokehBlurNode(b_node);
304                         break;
305                 case CMP_NODE_DILATEERODE:
306                         node = new DilateErodeNode(b_node);
307                         break;
308                 case CMP_NODE_INPAINT:
309                         node = new InpaintNode(b_node);
310                         break;
311                 case CMP_NODE_DESPECKLE:
312                         node = new DespeckleNode(b_node);
313                         break;
314                 case CMP_NODE_LENSDIST:
315                         node = new LensDistortionNode(b_node);
316                         break;
317                 case CMP_NODE_RGB:
318                         node = new ColorNode(b_node);
319                         break;
320                 case CMP_NODE_VALUE:
321                         node = new ValueNode(b_node);
322                         break;
323                 case CMP_NODE_TIME:
324                         node = new TimeNode(b_node);
325                         break;
326                 case CMP_NODE_DBLUR:
327                         node = new DirectionalBlurNode(b_node);
328                         break;
329                 case CMP_NODE_ZCOMBINE:
330                         node = new ZCombineNode(b_node);
331                         break;
332                 case CMP_NODE_TONEMAP:
333                         node = new TonemapNode(b_node);
334                         break;
335                 case CMP_NODE_SWITCH:
336                         node = new SwitchNode(b_node);
337                         break;
338                 case CMP_NODE_GLARE:
339                         node = new GlareNode(b_node);
340                         break;
341                 case CMP_NODE_MOVIECLIP:
342                         node = new MovieClipNode(b_node);
343                         break;
344                 case CMP_NODE_COLOR_SPILL:
345                         node = new ColorSpillNode(b_node);
346                         break;
347                 case CMP_NODE_OUTPUT_FILE:
348                         node = new OutputFileNode(b_node);
349                         break;
350                 case CMP_NODE_MAP_VALUE:
351                         node = new MapValueNode(b_node);
352                         break;
353                 case CMP_NODE_TRANSFORM:
354                         node = new TransformNode(b_node);
355                         break;
356                 case CMP_NODE_STABILIZE2D:
357                         node = new Stabilize2dNode(b_node);
358                         break;
359                 case CMP_NODE_BILATERALBLUR:
360                         node = new BilateralBlurNode(b_node);
361                         break;
362                 case CMP_NODE_VECBLUR:
363                         node = new VectorBlurNode(b_node);
364                         break;
365                 case CMP_NODE_MOVIEDISTORTION:
366                         node = new MovieDistortionNode(b_node);
367                         break;
368                 case CMP_NODE_VIEW_LEVELS:
369                         node = new ViewLevelsNode(b_node);
370                         break;
371                 case CMP_NODE_DEFOCUS:
372                         node = new DefocusNode(b_node);
373                         break;
374                 case CMP_NODE_DOUBLEEDGEMASK:
375                         node = new DoubleEdgeMaskNode(b_node);
376                         break;
377                 case CMP_NODE_CROP:
378                         node = new CropNode(b_node);
379                         break;
380                 case CMP_NODE_MASK:
381                         node = new MaskNode(b_node);
382                         break;
383                 case CMP_NODE_KEYINGSCREEN:
384                         node = new KeyingScreenNode(b_node);
385                         break;
386                 case CMP_NODE_KEYING:
387                         node = new KeyingNode(b_node);
388                         break;
389                 case CMP_NODE_TRACKPOS:
390                         node = new TrackPositionNode(b_node);
391                         break;
392                 /* not inplemented yet */
393                 default:
394                         node = new MuteNode(b_node);
395                         break;
396         }
397         return node;
398 }
399 void Converter::convertDataType(SocketConnection *connection, ExecutionSystem *system)
400 {
401         OutputSocket *outputSocket = connection->getFromSocket();
402         InputSocket *inputSocket = connection->getToSocket();
403         DataType fromDatatype = outputSocket->getDataType();
404         DataType toDatatype = inputSocket->getDataType();
405         NodeOperation *converter = NULL;
406         if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_COLOR) {
407                 converter = new ConvertValueToColorProg();
408         }
409         else if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_VECTOR) {
410                 converter = new ConvertValueToVectorOperation();
411         }
412         else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VALUE) {
413                 converter = new ConvertColorToValueProg();
414         }
415         else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VECTOR) {
416                 converter = new ConvertColorToVectorOperation();
417         }
418         else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_VALUE) {
419                 converter = new ConvertVectorToValueOperation();
420         }
421         else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_COLOR) {
422                 converter = new ConvertVectorToColorOperation();
423         }
424         if (converter != NULL) {
425                 inputSocket->relinkConnections(converter->getInputSocket(0));
426                 ExecutionSystemHelper::addLink(system->getConnections(), converter->getOutputSocket(), inputSocket);
427                 system->addOperation(converter);
428         }
429 }
430
431 void Converter::convertResolution(SocketConnection *connection, ExecutionSystem *system)
432 {
433         InputSocketResizeMode mode = connection->getToSocket()->getResizeMode();
434
435         NodeOperation *toOperation = (NodeOperation *)connection->getToNode();
436         const float toWidth = toOperation->getWidth();
437         const float toHeight = toOperation->getHeight();
438         NodeOperation *fromOperation = (NodeOperation *)connection->getFromNode();
439         const float fromWidth = fromOperation->getWidth();
440         const float fromHeight = fromOperation->getHeight();
441         bool doCenter = false;
442         bool doScale = false;
443         float addX = (toWidth - fromWidth) / 2.0f;
444         float addY = (toHeight - fromHeight) / 2.0f;
445         float scaleX = 0;
446         float scaleY = 0;
447
448         switch (mode) {
449                 case COM_SC_NO_RESIZE:
450                         break;
451                 case COM_SC_CENTER:
452                         doCenter = true;
453                         break;
454                 case COM_SC_FIT_WIDTH:
455                         doCenter = true;
456                         doScale = true;
457                         scaleX = scaleY = toWidth / fromWidth;
458                         break;
459                 case COM_SC_FIT_HEIGHT:
460                         doCenter = true;
461                         doScale = true;
462                         scaleX = scaleY = toHeight / fromHeight;
463                         break;
464                 case COM_SC_FIT:
465                         doCenter = true;
466                         doScale = true;
467                         scaleX = toWidth / fromWidth;
468                         scaleY = toHeight / fromHeight;
469                         if (scaleX < scaleY) {
470                                 scaleX = scaleY;
471                         }
472                         else {
473                                 scaleY = scaleX;
474                         }
475                         break;
476                 case COM_SC_STRETCH:
477                         doCenter = true;
478                         doScale = true;
479                         scaleX = toWidth / fromWidth;
480                         scaleY = toHeight / fromHeight;
481                         break;
482
483         }
484
485         if (doCenter) {
486                 NodeOperation *first = NULL;
487                 SocketConnection *c;
488                 ScaleOperation *scaleOperation = NULL;
489                 if (doScale) {
490                         scaleOperation = new ScaleOperation();
491                         first = scaleOperation;
492                         SetValueOperation *sxop = new SetValueOperation();
493                         sxop->setValue(scaleX);
494                         c = ExecutionSystemHelper::addLink(system->getConnections(), sxop->getOutputSocket(), scaleOperation->getInputSocket(1));
495                         c->setIgnoreResizeCheck(true);
496                         SetValueOperation *syop = new SetValueOperation();
497                         syop->setValue(scaleY);
498                         c = ExecutionSystemHelper::addLink(system->getConnections(), syop->getOutputSocket(), scaleOperation->getInputSocket(2));
499                         c->setIgnoreResizeCheck(true);
500                         system->addOperation(sxop);
501                         system->addOperation(syop);
502
503                         unsigned int resolution[2] = {fromWidth, fromHeight};
504                         scaleOperation->setResolution(resolution);
505                         sxop->setResolution(resolution);
506                         syop->setResolution(resolution);
507                         system->addOperation(scaleOperation);
508
509                         c->setIgnoreResizeCheck(true);
510                 }
511
512                 TranslateOperation *translateOperation = new TranslateOperation();
513                 if (!first) first = translateOperation;
514                 SetValueOperation *xop = new SetValueOperation();
515                 xop->setValue(addX);
516                 c = ExecutionSystemHelper::addLink(system->getConnections(), xop->getOutputSocket(), translateOperation->getInputSocket(1));
517                 c->setIgnoreResizeCheck(true);
518                 SetValueOperation *yop = new SetValueOperation();
519                 yop->setValue(addY);
520                 c = ExecutionSystemHelper::addLink(system->getConnections(), yop->getOutputSocket(), translateOperation->getInputSocket(2));
521                 c->setIgnoreResizeCheck(true);
522                 system->addOperation(xop);
523                 system->addOperation(yop);
524
525                 unsigned int resolution[2] = {toWidth, toHeight};
526                 translateOperation->setResolution(resolution);
527                 xop->setResolution(resolution);
528                 yop->setResolution(resolution);
529                 system->addOperation(translateOperation);
530
531                 if (doScale) {
532                         c = ExecutionSystemHelper::addLink(system->getConnections(), scaleOperation->getOutputSocket(), translateOperation->getInputSocket(0));
533                         c->setIgnoreResizeCheck(true);
534                 }
535
536                 InputSocket *inputSocket = connection->getToSocket();
537                 inputSocket->relinkConnections(first->getInputSocket(0));
538                 c = ExecutionSystemHelper::addLink(system->getConnections(), translateOperation->getOutputSocket(), inputSocket);
539                 c->setIgnoreResizeCheck(true);
540         }
541
542         connection->setIgnoreResizeCheck(true);
543 }