Fixing warnings from doxygen:
[synfig.git] / synfig-core / trunk / src / modules / lyr_std / supersample.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file supersample.cpp
3 **      \brief Template Header
4 **
5 **      \legal
6 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
7 **
8 **      This package is free software; you can redistribute it and/or
9 **      modify it under the terms of the GNU General Public License as
10 **      published by the Free Software Foundation; either version 2 of
11 **      the License, or (at your option) any later version.
12 **
13 **      This package is distributed in the hope that it will be useful,
14 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
15 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 **      General Public License for more details.
17 **      \endlegal
18 **
19 ** === N O T E S ===========================================================
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 "supersample.h"
33 #include <synfig/string.h>
34 #include <synfig/time.h>
35 #include <synfig/context.h>
36 #include <synfig/paramdesc.h>
37 #include <synfig/renddesc.h>
38 #include <synfig/surface.h>
39 #include <synfig/value.h>
40 #include <synfig/valuenode.h>
41
42 #include <synfig/target.h>
43 #include <synfig/render.h>
44
45 #endif
46
47 /* === M A C R O S ========================================================= */
48
49 /* === G L O B A L S ======================================================= */
50
51 SYNFIG_LAYER_INIT(SuperSample);
52 SYNFIG_LAYER_SET_NAME(SuperSample,"super_sample");
53 SYNFIG_LAYER_SET_LOCAL_NAME(SuperSample,_("Super Sample"));
54 SYNFIG_LAYER_SET_CATEGORY(SuperSample,_("Other"));
55 SYNFIG_LAYER_SET_VERSION(SuperSample,"0.1");
56 SYNFIG_LAYER_SET_CVS_ID(SuperSample,"$Id: supersample.cpp,v 1.1.1.1 2005/01/04 01:23:10 darco Exp $");
57
58 /* === P R O C E D U R E S ================================================= */
59
60 /* === M E T H O D S ======================================================= */
61
62 SuperSample::SuperSample():width(2),height(2)
63 {
64         scanline=false;
65         alpha_aware=true;
66 }
67
68 bool
69 SuperSample::set_param(const String & param, const ValueBase &value)
70 {
71
72         IMPORT(width);
73         IMPORT(height);
74         IMPORT(scanline);
75         IMPORT(alpha_aware);
76
77         return false;
78 }
79
80 ValueBase
81 SuperSample::get_param(const String& param)const
82 {
83         EXPORT(width);
84         EXPORT(height);
85     EXPORT(scanline);
86     EXPORT(alpha_aware);
87
88         EXPORT_NAME();
89         EXPORT_VERSION();
90
91         return ValueBase();
92 }
93
94 bool
95 SuperSample::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
96 {
97         // don't bother supersampling if our quality is too low.
98         if(quality>=10)
99                 return context.accelerated_render(surface,quality,renddesc,cb);
100
101         RendDesc desc(renddesc);
102
103         SuperCallback subcb(cb,1,9000,10000);
104         SuperCallback stagetwo(cb,9000,10000,10000);
105
106         desc.clear_flags();
107         desc.set_wh(desc.get_w()*width,desc.get_h()*height);
108
109         Surface tempsurface;
110
111         // Render the scene
112         if(scanline)
113         {
114                 handle<Target> target=surface_target(&tempsurface);
115                 if(!target)
116                 {
117                         if(cb)cb->error(_("Unable to create SurfaceTarget"));
118                         return false;
119                 }
120                 target->set_rend_desc(&desc);
121
122                 if(!render(context-1,target,desc,&subcb))
123                 {
124                         if(cb)cb->error(strprintf(__FILE__"%d: Scanline Renderer Failure",__LINE__));
125                         return false;
126                 }
127         }
128         else
129                 if(!context.accelerated_render(&tempsurface,quality,desc,cb))
130                 {
131                         //if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
132                         return false;
133                 }
134
135         surface->set_wh(renddesc.get_w(),renddesc.get_h());
136
137         Surface::pen pen(surface->begin());
138         Surface::pen temp_pen(tempsurface.begin());
139
140         if(cb && !cb->amount_complete(9001,10000)) return false;
141
142         if(alpha_aware)
143         {
144                 int x,y,u,v;
145                 float sum;
146                 Color pool;
147                 for(y=0;y<surface->get_h();y++,pen.inc_y(),pen.dec_x(x),temp_pen.inc_y(height),temp_pen.dec_x(x*width))
148                 {
149                         for(x=0;x<surface->get_w();x++,pen.inc_x(),temp_pen.inc_x(width))
150                         {
151                                 pool=Color(0,0,0,0);
152                                 sum=0;
153
154                                 for(v=0;v<height;v++,temp_pen.inc_y(),temp_pen.dec_x(u))
155                                         for(u=0;u<width;u++,temp_pen.inc_x())
156                                         {
157                                                 pool+=temp_pen.get_value()*temp_pen.get_value().get_a();
158                                                 sum+=temp_pen.get_value().get_a();
159                                         }
160                                 temp_pen.dec_y(v);
161
162                                 if(sum)
163                                 {
164                                         pool/=sum;
165                                         pool.set_a(sum/float(width*height));
166                                         pen.put_value(pool);
167                                 }
168                                 else
169                                         pen.put_value(Color::alpha());
170                         }
171                         if(y&31==0 && cb)
172                         {
173                                 if(!stagetwo.amount_complete(y,surface->get_h()))
174                                         return false;
175                         }
176                 }
177         }
178         else
179         {
180                 int x,y,u,v;
181                 Color pool;
182                 float multiplier=1.0f/float(width*height);
183                 for(y=0;y<surface->get_h();y++,pen.inc_y(),pen.dec_x(x),temp_pen.inc_y(height),temp_pen.dec_x(x*width))
184                 {
185                         for(x=0;x<surface->get_w();x++,pen.inc_x(),temp_pen.inc_x(width))
186                         {
187                                 pool=Color(0,0,0,0);
188                                 for(v=0;v<height;v++,temp_pen.inc_y(),temp_pen.dec_x(u))
189                                         for(u=0;u<width;u++,temp_pen.inc_x())
190                                                 pool+=temp_pen.get_value();
191                                 temp_pen.dec_y(v);
192                                 pen.put_value(pool*multiplier);
193                         }
194                         if(y&31==0 && cb)
195                         {
196                                 if(!stagetwo.amount_complete(y,surface->get_h()))
197                                         return false;
198                         }
199                 }
200         }
201
202         if(cb && !cb->amount_complete(10000,10000)) return false;
203
204         return true;
205 }
206
207 Layer::Vocab
208 SuperSample::get_param_vocab(void)const
209 {
210         Layer::Vocab ret;
211
212         ret.push_back(ParamDesc("width")
213                 .set_local_name(_("Width"))
214                 .set_description(_("Width of sample area (In pixels)"))
215         );
216         ret.push_back(ParamDesc("height")
217                 .set_local_name(_("Height"))
218                 .set_description(_("Height of sample area (In pixels)"))
219         );
220         ret.push_back(ParamDesc("scanline")
221                 .set_local_name(_("Use Parametric"))
222                 .set_description(_("Use the Parametric Renderer"))
223         );
224         ret.push_back(ParamDesc("alpha_aware")
225                 .set_local_name(_("Be Alpha Safe"))
226         );
227
228         return ret;
229 }
230
231 Rect
232 SuperSample::get_bounding_rect(Context context)const
233 {
234         return context.get_full_bounding_rect();
235 }