I put stuff into the code that shouldn't have been there. Reverts this small stateme...
[blender.git] / release / plugins / sequence / blur.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <stdio.h>
34 #include "plugin.h"
35
36 /* ******************** GLOBAL VARIABLES ***************** */
37
38
39 char name[24]= "Blur";  
40
41 /* structure for buttons, 
42  *  butcode      name           default  min  max  0
43  */
44
45 VarStruct varstr[]= {
46         LABEL,                  "Input: 1 strip", 0.0, 0.0, 0.0, "", 
47         NUMSLI|FLO,             "Blur",         0.5,    0.0,    10.0, "Maximum filtersize", 
48         NUMSLI|FLO,             "Gamma",        1.0,    0.4,    2.0, "Gamma correction", 
49         TOG|INT,                "Animated",     0.0,    0.0,    1.0, "For (Ipo) animated blur", 
50         NUM|INT,                "debug",        0.0,    0.0,    2.0,
51                 "0:off 1: show primary blur buffer 2: show 2nd blur buffer", 
52
53 };
54
55 /* The cast struct is for input in the main doit function
56    Varstr and Cast must have the same variables in the same order */ 
57
58 typedef struct Cast {
59         int dummy;                      /* because of the 'label' button */
60         float blur;
61         float gamma;
62         float use_ipo;
63         int show;
64 } Cast;
65
66
67 /* cfra: the current frame */
68
69 float cfra;
70
71 void plugin_seq_doit(Cast *, float, float, int, int, ImBuf *, ImBuf *, ImBuf *, ImBuf *);
72
73 /* ******************** Fixed functions ***************** */
74
75 int plugin_seq_getversion(void) 
76 {
77         return B_PLUGIN_VERSION;
78 }
79
80 void plugin_but_changed(int but) 
81 {
82 }
83
84 void plugin_init(void)
85 {
86 }
87
88 void plugin_getinfo(PluginInfo *info)
89 {
90         info->name= name;
91         info->nvars= sizeof(varstr)/sizeof(VarStruct);
92         info->cfra= &cfra;
93
94         info->varstr= varstr;
95
96         info->init= plugin_init;
97         info->seq_doit= (SeqDoit) plugin_seq_doit;
98         info->callback= plugin_but_changed;
99 }
100
101
102 void blurbuf(struct ImBuf *ibuf, int nr, Cast *cast)
103 {
104         /* nr = number of blurs */
105         /* the ibuf->rect is replaced */
106         struct ImBuf *tbuf, *ttbuf;
107         int i, x4;
108         
109         tbuf= dupImBuf(ibuf);
110         x4= ibuf->x/4;
111         
112         /* This doesn't seem to work... paprmh */
113         if(cast->gamma != 1.0) gamwarp(tbuf, cast->gamma);
114
115         /* reduce */
116         for(i=0; i<nr; i++) {
117                 ttbuf = onehalf(tbuf);
118                 if (ttbuf) {
119                         freeImBuf(tbuf);
120                         tbuf = ttbuf;
121                 }
122                 if(tbuf->x<4 || tbuf->y<4) break;
123         }
124
125         /* enlarge */
126         for(i=0; i<nr; i++) {
127                 ttbuf = double_x(tbuf);
128                 if (ttbuf) {
129                         freeImBuf(tbuf);
130                         tbuf = ttbuf;
131                 }
132                 ttbuf = double_y(tbuf);
133                 if (ttbuf) {
134                         freeImBuf(tbuf);
135                         tbuf = ttbuf;
136                 }
137                 if(tbuf->x > x4) {
138                         scaleImBuf(tbuf, ibuf->x, ibuf->y);
139                         break;
140                 }
141         }
142         
143         /* this doesn't seem to work...paprmh*/
144         if(cast->gamma != 1.0) gamwarp(tbuf, 1.0 / cast->gamma);
145
146         if(ibuf->rect)memcpy(ibuf->rect, tbuf->rect, 4*ibuf->x*ibuf->y);
147
148         if(ibuf->rect_float) 
149                 memcpy(ibuf->rect_float, tbuf->rect_float, 4*ibuf->x*ibuf->y*sizeof(float));
150
151         freeImBuf(tbuf);
152         
153 }
154
155 void doblur(struct ImBuf *mbuf, float fac, Cast *cast)
156 {
157         /* make two filtered images, like a mipmap structure
158          * fac is filtersize in pixels
159          */
160         struct ImBuf *ibuf, *pbuf;
161         float ifac, pfac, infac;
162         int n, b1, b2;
163         char *irect, *prect, *mrect;
164         float *irectf, *prectf, *mrectf;
165         
166         /* wich buffers ? */
167                                 
168         if(fac>7.0) fac= 7.0;
169         if(fac<=1.0) return;
170         
171         pfac= 2.0;
172         pbuf= dupImBuf(mbuf);
173         n= 1;
174         while(pfac < fac) {
175                 blurbuf(pbuf, n, cast);
176                 blurbuf(pbuf, n, cast);
177                 
178                 n++;
179                 pfac+= 1.0;
180         }
181
182         ifac= pfac;
183         pfac-= 1.0;
184
185         ibuf= dupImBuf(pbuf);
186         blurbuf(ibuf, n, cast);
187         blurbuf(ibuf, n, cast);
188         
189         fac= (fac-pfac)/(ifac-pfac);
190         n= mbuf->x*mbuf->y;
191         
192         if(cast->show) fac=cast->show-1;
193         
194         if(mbuf->rect_float){
195                 if(fac>=1) {
196                         memcpy(mbuf->rect_float, ibuf->rect_float, 4*n*sizeof(float));
197                 }
198                 else if(fac<=0) {
199                         memcpy(mbuf->rect_float, pbuf->rect_float, 4*n*sizeof(float));
200                 }
201                 else {  /* interpolate */
202                         infac= 1-fac;
203                         
204                         irectf= (float *)ibuf->rect_float;
205                         prectf= (float *)pbuf->rect_float;
206                         mrectf= (float *)mbuf->rect_float;
207                         while(n--) {
208                                 mrectf[0]= irectf[0]*fac+ prectf[0]*infac;
209                                 mrectf[1]= irectf[1]*fac+ prectf[1]*infac;
210                                 mrectf[2]= irectf[2]*fac+ prectf[2]*infac;
211                                 mrectf[3]= irectf[3]*fac+ prectf[3]*infac;
212                                 mrectf+= 4;
213                                 irectf+= 4;
214                                 prectf+= 4;
215                         }
216                 }
217         }       
218         else if(mbuf->rect){
219                 b1= (int)fac*255.0;
220                 if(b1>255) b1= 255;
221                 b2= 255-b1;
222         
223                 if(b1==255) {
224                         memcpy(mbuf->rect, ibuf->rect, 4*n);
225                 }
226                 else if(b1==0) {
227                         memcpy(mbuf->rect, pbuf->rect, 4*n);
228                 }
229                 else {  /* interpolate */
230                         irect= (char *)ibuf->rect;
231                         prect= (char *)pbuf->rect;
232                         mrect= (char *)mbuf->rect;
233                         while(n--) {
234                                 mrect[0]= (irect[0]*b1+ prect[0]*b2)>>8;
235                                 mrect[1]= (irect[1]*b1+ prect[1]*b2)>>8;
236                                 mrect[2]= (irect[2]*b1+ prect[2]*b2)>>8;
237                                 mrect[3]= (irect[3]*b1+ prect[3]*b2)>>8;
238                                 mrect+= 4;
239                                 irect+= 4;
240                                 prect+= 4;
241                         }
242                 }
243         }
244
245         freeImBuf(ibuf);
246         freeImBuf(pbuf);
247 }
248
249
250 void plugin_seq_doit(Cast *cast, float facf0, float facf1, int x, int y, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *out, ImBuf *use)
251 {
252         float  bfacf0, bfacf1;
253         
254         if(cast->use_ipo==0) {
255                 bfacf0= bfacf1= cast->blur+1.0;
256         }
257         else {
258                 bfacf0 = (facf0 * 6.0) + 1.0;
259                 bfacf1 = (facf1 * 6.0) + 1.0;
260         }
261
262         if(out->rect) memcpy(out->rect, ibuf1->rect, 4*out->x*out->y);
263         if(out->rect_float) memcpy(out->rect_float, ibuf1->rect_float, 4*out->x*out->y*sizeof(float));
264         
265 /****************I can't get this field code to work... works ok without...paprmh****************/
266
267
268         /* it blurs interlaced, only tested with even fields */
269
270 /*      de_interlace(out);*/
271         /* otherwise scaling goes wrong */
272 /*      out->flags &= ~IB_fields;*/
273         
274         doblur(out, bfacf0, cast); /*fieldA*/
275
276 /*      if(out->rect)out->rect += out->x * out->y;
277         if(out->rect_float)out->rect_float += out->x * out->y;
278                 
279         doblur(out, bfacf1, cast);*/ /*fieldB*/
280
281 /*      if(out->rect)out->rect -= out->x * out->y;
282         if(out->rect_float)out->rect_float -= out->x * out->y;
283         out->flags |= IB_fields;
284
285         interlace(out);*/
286         
287 }
288