Initial Stable Commit
[synfig.git] / synfig-core / trunk / src / sinfg / layer_motionblur.cpp
1 /* === S I N F G =========================================================== */
2 /*!     \file layer_motionblur.h
3 **      \brief Template Header
4 **
5 **      $Id: layer_motionblur.cpp,v 1.1.1.1 2005/01/04 01:23:14 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === H E A D E R S ======================================================= */
23
24 #ifdef USING_PCH
25 #       include "pch.h"
26 #else
27 #ifdef HAVE_CONFIG_H
28 #       include <config.h>
29 #endif
30
31 #include "string.h"
32 #include "layer_motionblur.h"
33 #include "time.h"
34 #include "context.h"
35 #include "paramdesc.h"
36 #include "renddesc.h"
37 #include "surface.h"
38 #include "value.h"
39 #include "valuenode.h"
40 #include "canvas.h"
41
42 #endif
43
44 /* === U S I N G =========================================================== */
45
46 using namespace sinfg;
47 using namespace etl;
48 using namespace std;
49
50 /* === G L O B A L S ======================================================= */
51
52 SINFG_LAYER_INIT(Layer_MotionBlur);
53 SINFG_LAYER_SET_NAME(Layer_MotionBlur,"MotionBlur");
54 SINFG_LAYER_SET_LOCAL_NAME(Layer_MotionBlur,_("Motion Blur"));
55 SINFG_LAYER_SET_CATEGORY(Layer_MotionBlur,_("Blurs"));
56 SINFG_LAYER_SET_VERSION(Layer_MotionBlur,"0.1");
57 SINFG_LAYER_SET_CVS_ID(Layer_MotionBlur,"$Id: layer_motionblur.cpp,v 1.1.1.1 2005/01/04 01:23:14 darco Exp $");
58
59 /* === M E M B E R S ======================================================= */
60
61 Layer_MotionBlur::Layer_MotionBlur():
62         Layer_Composite (1.0,Color::BLEND_STRAIGHT),
63         aperture                (0)
64 {
65 }
66         
67 bool
68 Layer_MotionBlur::set_param(const String &param, const ValueBase &value)
69 {
70
71         IMPORT(aperture);               
72         return Layer_Composite::set_param(param,value);
73 }
74
75 ValueBase
76 Layer_MotionBlur::get_param(const String &param)const
77 {
78         EXPORT(aperture);
79         
80         EXPORT_NAME();
81         EXPORT_VERSION();
82                 
83         return Layer_Composite::get_param(param);
84 }
85
86 void
87 Layer_MotionBlur::set_time(Context context, Time time)const
88 {
89         context.set_time(time);
90         time_cur=time;
91 }
92
93 void
94 Layer_MotionBlur::set_time(Context context, Time time, const Point &pos)const
95 {
96         context.set_time(time,pos);
97         time_cur=time;
98 }
99
100 Color
101 Layer_MotionBlur::get_color(Context context, const Point &pos)const
102 {
103 /*      if(aperture)
104         {
105                 Time time(time_cur);
106                 time+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) *aperture -aperture*0.5;
107                 context.set_time(time, pos);
108         }       
109 */
110         return context.get_color(pos);
111 }
112
113 Layer::Vocab
114 Layer_MotionBlur::get_param_vocab()const
115 {
116         Layer::Vocab ret;
117         //ret=Layer_Composite::get_param_vocab();
118         
119         ret.push_back(ParamDesc("aperture")
120                 .set_local_name(_("Aperature"))
121                 .set_description(_("Shutter Time"))
122         );
123         
124         return ret;
125 }
126
127 bool
128 Layer_MotionBlur::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
129 {
130         if(aperture && quality<10)
131         {
132                 //int x, y;
133                 SuperCallback subimagecb;
134                 int samples=1;
135                 switch(quality)
136                 {
137                         case 1: // Production Quality
138                                 samples=32;
139                                 break;
140                         case 2: // Excellent Quality
141                                 samples=24;
142                                 break;
143                         case 3: // Good Quality
144                                 samples=16;
145                                 break;
146                         case 4: // Moderate Quality
147                                 samples=12;
148                                 break;
149                         case 5: // Draft Quality
150                                 samples=7;
151                                 break;
152                         case 6:
153                                 samples=6;
154                                 break;
155                         case 7:
156                                 samples=5;
157                                 break;
158                         case 8:
159                                 samples=3;
160                                 break;
161                         case 9:
162                                 samples=3;
163                                 break;
164                         case 10: // Rough Quality
165             default:                    
166                                 samples=1;
167                                 break;
168                                 
169                 }
170         
171                 Surface tmp;
172                 int i;
173
174                 surface->set_wh(renddesc.get_w(),renddesc.get_h());
175                 surface->clear();
176                 
177                 for(i=0;i<samples;i++)
178                 {
179                         subimagecb=SuperCallback(cb,i*(5000/samples),(i+1)*(5000/samples),5000);
180                         context.set_time(time_cur+(aperture/samples)*i-aperture*0.5);
181                         if(!context.accelerated_render(&tmp,quality,renddesc,&subimagecb))
182                                 return false;
183                         for(int y=0;y<renddesc.get_h();y++)
184                                 for(int x=0;x<renddesc.get_w();x++)
185                                         (*surface)[y][x]+=tmp[y][x].premult_alpha();
186                 }
187                 for(int y=0;y<renddesc.get_h();y++)
188                         for(int x=0;x<renddesc.get_w();x++)
189                                 (*surface)[y][x]=((*surface)[y][x]/(float)samples).demult_alpha();
190         }
191         else
192                 return context.accelerated_render(surface,quality,renddesc,cb);
193         
194         return true;
195 }