Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / synfig-core / tags / synfig_0_61_06 / src / synfig / layer_motionblur.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file layer_motionblur.cpp
3 **      \brief Template Header
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === H E A D E R S ======================================================= */
24
25 #ifdef USING_PCH
26 #       include "pch.h"
27 #else
28 #ifdef HAVE_CONFIG_H
29 #       include <config.h>
30 #endif
31
32 #include "string.h"
33 #include "layer_motionblur.h"
34 #include "time.h"
35 #include "context.h"
36 #include "paramdesc.h"
37 #include "renddesc.h"
38 #include "surface.h"
39 #include "value.h"
40 #include "valuenode.h"
41 #include "canvas.h"
42
43 #endif
44
45 /* === U S I N G =========================================================== */
46
47 using namespace synfig;
48 using namespace etl;
49 using namespace std;
50
51 /* === G L O B A L S ======================================================= */
52
53 SYNFIG_LAYER_INIT(Layer_MotionBlur);
54 SYNFIG_LAYER_SET_NAME(Layer_MotionBlur,"MotionBlur");
55 SYNFIG_LAYER_SET_LOCAL_NAME(Layer_MotionBlur,_("Motion Blur"));
56 SYNFIG_LAYER_SET_CATEGORY(Layer_MotionBlur,_("Blurs"));
57 SYNFIG_LAYER_SET_VERSION(Layer_MotionBlur,"0.1");
58 SYNFIG_LAYER_SET_CVS_ID(Layer_MotionBlur,"$Id$");
59
60 /* === M E M B E R S ======================================================= */
61
62 Layer_MotionBlur::Layer_MotionBlur():
63         Layer_Composite (1.0,Color::BLEND_STRAIGHT),
64         aperture                (0)
65 {
66 }
67
68 bool
69 Layer_MotionBlur::set_param(const String &param, const ValueBase &value)
70 {
71
72         IMPORT(aperture);
73         return Layer_Composite::set_param(param,value);
74 }
75
76 ValueBase
77 Layer_MotionBlur::get_param(const String &param)const
78 {
79         EXPORT(aperture);
80
81         EXPORT_NAME();
82         EXPORT_VERSION();
83
84         return Layer_Composite::get_param(param);
85 }
86
87 void
88 Layer_MotionBlur::set_time(Context context, Time time)const
89 {
90         context.set_time(time);
91         time_cur=time;
92 }
93
94 void
95 Layer_MotionBlur::set_time(Context context, Time time, const Point &pos)const
96 {
97         context.set_time(time,pos);
98         time_cur=time;
99 }
100
101 Color
102 Layer_MotionBlur::get_color(Context context, const Point &pos)const
103 {
104 /*      if(aperture)
105         {
106                 Time time(time_cur);
107                 time+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) *aperture -aperture*0.5;
108                 context.set_time(time, pos);
109         }
110 */
111         return context.get_color(pos);
112 }
113
114 Layer::Vocab
115 Layer_MotionBlur::get_param_vocab()const
116 {
117         Layer::Vocab ret;
118         //ret=Layer_Composite::get_param_vocab();
119
120         ret.push_back(ParamDesc("aperture")
121                 .set_local_name(_("Aperture"))
122                 .set_description(_("Shutter Time"))
123         );
124
125         return ret;
126 }
127
128 bool
129 Layer_MotionBlur::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
130 {
131         if(aperture && quality<10)
132         {
133                 //int x, y;
134                 SuperCallback subimagecb;
135                 int samples=1;
136                 switch(quality)
137                 {
138                         case 1: // Production Quality
139                                 samples=32;
140                                 break;
141                         case 2: // Excellent Quality
142                                 samples=24;
143                                 break;
144                         case 3: // Good Quality
145                                 samples=16;
146                                 break;
147                         case 4: // Moderate Quality
148                                 samples=12;
149                                 break;
150                         case 5: // Draft Quality
151                                 samples=7;
152                                 break;
153                         case 6:
154                                 samples=6;
155                                 break;
156                         case 7:
157                                 samples=5;
158                                 break;
159                         case 8:
160                                 samples=3;
161                                 break;
162                         case 9:
163                                 samples=3;
164                                 break;
165                         case 10: // Rough Quality
166             default:
167                                 samples=1;
168                                 break;
169
170                 }
171
172                 Surface tmp;
173                 int i;
174
175                 surface->set_wh(renddesc.get_w(),renddesc.get_h());
176                 surface->clear();
177
178                 for(i=0;i<samples;i++)
179                 {
180                         subimagecb=SuperCallback(cb,i*(5000/samples),(i+1)*(5000/samples),5000);
181                         context.set_time(time_cur+(aperture/samples)*i-aperture*0.5);
182                         if(!context.accelerated_render(&tmp,quality,renddesc,&subimagecb))
183                                 return false;
184                         for(int y=0;y<renddesc.get_h();y++)
185                                 for(int x=0;x<renddesc.get_w();x++)
186                                         (*surface)[y][x]+=tmp[y][x].premult_alpha();
187                 }
188                 for(int y=0;y<renddesc.get_h();y++)
189                         for(int x=0;x<renddesc.get_w();x++)
190                                 (*surface)[y][x]=((*surface)[y][x]/(float)samples).demult_alpha();
191         }
192         else
193                 return context.accelerated_render(surface,quality,renddesc,cb);
194
195         return true;
196 }