Fix compilation error of Cycles after recent py node removal
[blender-staging.git] / release / plugins / sequence / dnr.c
1 /*
2  * Dynamic Noise Reduction (based on the VirtualDub filter by Steven Don)
3  *
4  * Copyright (c) 2005 Peter Schlaile 
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
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.
15  *
16  */
17
18 #include <math.h>
19 #include "plugin.h"
20 #include <stdio.h>
21
22 char name[]= "Dynamic Noise Reduction";
23
24 VarStruct varstr[]= {
25         { NUMSLI|INT, "Level:", 10.0,   0.0,    15.0, "Level"}, 
26 };
27
28 typedef struct Cast {
29         int level;
30 } Cast;
31
32 float cfra;
33 void * plugin_private_data;
34
35 struct my_data {
36         unsigned char lookup_table[65536];
37         int last_level;
38         float last_cfra;
39         int last_width;
40         int last_height;
41         unsigned char * last_frame;
42 };
43
44 void plugin_seq_doit(Cast *, float, float, int, int, 
45                      ImBuf *, ImBuf *, ImBuf *, ImBuf *);
46
47 int plugin_seq_getversion(void) { return B_PLUGIN_VERSION;}
48
49 static void precalculate(unsigned char * table, int level)
50 {
51         int ap_, bp;
52
53         for (ap_ = 0; ap_ < 256; ap_++) {
54                 for (bp = 0; bp < 256; bp++) {
55                         int ap = ap_;
56                         int diff = ap - bp;
57                         if (diff < 0) {
58                                 diff = -diff;
59                         }
60                         if (diff < level) {
61                                 if (diff > (level >> 1)) {
62                                         ap = (ap + ap + bp)/3;
63                                 } else {
64                                         ap = bp;
65                                 }
66                         }
67                 
68                         *table++ = ap;
69                 }
70         }
71 }
72
73 void plugin_but_changed(int but) { }
74 void plugin_init() { }
75
76 void * plugin_seq_alloc_private_data()
77 {
78         struct my_data * result = (struct my_data*) calloc(
79                 sizeof(struct my_data), 1);
80         result->last_cfra = -1;
81         return result;
82 }
83
84 void plugin_seq_free_private_data(void * data)
85 {
86         struct my_data * d = (struct my_data*) data;
87         if (d->last_frame) {
88                 free(d->last_frame);
89         }
90         free(d);
91 }
92
93 void plugin_getinfo(PluginInfo *info)
94 {
95         info->name= name;
96         info->nvars= sizeof(varstr)/sizeof(VarStruct);
97         info->cfra= &cfra;
98
99         info->varstr= varstr;
100
101         info->init= plugin_init;
102         info->seq_doit= (SeqDoit) plugin_seq_doit;
103         info->callback= plugin_but_changed;
104 }
105
106 static void doit(unsigned char * src_, unsigned char * dst_,
107                  unsigned char * table, int width, int height)
108 {
109         int count = width * height;
110         unsigned char * src = src_;
111         unsigned char * dst = dst_;
112
113         while (count--) {
114                 *dst = table[(*src++ << 8) | *dst]; dst++;
115                 *dst = table[(*src++ << 8) | *dst]; dst++;
116                 *dst = table[(*src++ << 8) | *dst]; dst++;
117                 *dst++ = *src++;
118         }
119
120         memcpy(src_, dst_, width * height * 4);
121 }
122
123 void plugin_seq_doit(Cast *cast, float facf0, float facf1, int width, 
124         int height, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *out, ImBuf *use) {
125
126         struct my_data * d = (struct my_data*) plugin_private_data;
127
128         if (!ibuf1) return;
129
130         if (cast->level != d->last_level) {
131                 precalculate(d->lookup_table, cast->level);
132                 d->last_level = cast->level;
133         }
134
135         if (width != d->last_width || height != d->last_height ||
136             cfra != d->last_cfra + 1)
137         {
138                 free(d->last_frame);
139                 d->last_frame = (unsigned char*) calloc(width * height, 4);
140                 
141                 d->last_width = width;
142                 d->last_height = height;
143         }
144
145         memcpy(out->rect, ibuf1->rect, width * height * 4);
146
147         doit((unsigned char*) out->rect, 
148              d->last_frame, d->lookup_table, width, height);
149         
150         d->last_cfra = cfra;
151 }