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