r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / plugins / timeavg / timeavg.C
blob5b7d9a387d753313dead5176ac6031f9a4f7bdd2
1 #include "clip.h"
2 #include "defaults.h"
3 #include "filexml.h"
4 #include "keyframe.h"
5 #include "picon_png.h"
6 #include "timeavg.h"
7 #include "timeavgwindow.h"
8 #include "vframe.h"
10 #include <libintl.h>
11 #define _(String) gettext(String)
12 #define gettext_noop(String) String
13 #define N_(String) gettext_noop (String)
18 #include <stdint.h>
19 #include <string.h>
24 REGISTER_PLUGIN(TimeAvgMain)
30 TimeAvgConfig::TimeAvgConfig()
32         frames = 1;
37 TimeAvgMain::TimeAvgMain(PluginServer *server)
38  : PluginVClient(server)
40         PLUGIN_CONSTRUCTOR_MACRO
41         accumulation = 0;
42         history = 0;
43         history_size = 0;
46 TimeAvgMain::~TimeAvgMain()
48 //printf("TimeAvgMain::~TimeAvgMain 1\n");
49         PLUGIN_DESTRUCTOR_MACRO
51         if(accumulation) delete [] accumulation;
52         if(history)
53         {
54                 for(int i = 0; i < config.frames; i++)
55                         delete history[i];
56                 delete [] history;
57         }
60 char* TimeAvgMain::plugin_title() { return _("Time Average"); }
61 int TimeAvgMain::is_realtime() { return 1; }
64 NEW_PICON_MACRO(TimeAvgMain)
66 SHOW_GUI_MACRO(TimeAvgMain, TimeAvgThread)
68 SET_STRING_MACRO(TimeAvgMain)
70 RAISE_WINDOW_MACRO(TimeAvgMain);
74 int TimeAvgMain::process_realtime(VFrame *input, VFrame *output)
76         int h = input->get_h();
77         int w = input->get_w();
78         int color_model = input->get_color_model();
80         load_configuration();
82         if(!accumulation)
83         {
84                 accumulation = new int[w * h * cmodel_components(color_model)];
85                 bzero(accumulation, sizeof(int) * w * h * cmodel_components(color_model));
86         }
88         if(history)
89         {
90                 if(config.frames != history_size)
91                 {
92                         VFrame **history2;
93                         history2 = new VFrame*[config.frames];
95 // Copy existing frames over
96                         int i, j;
97                         for(i = 0, j = 0; i < config.frames && j < history_size; i++, j++)
98                                 history2[i] = history[j];
100 // Delete extra previous frames
101                         for( ; j < history_size; j++)
102                                 delete history[j];
103                         delete [] history;
105 // Create new frames
106                         for( ; i < config.frames; i++)
107                                 history2[i] = new VFrame(0, w, h, color_model);
109                         history = history2;
110                         history_size = config.frames;
112 for(i = 0; i < config.frames; i++)
113         bzero(history[i]->get_data(), history[i]->get_data_size());
115 bzero(accumulation, sizeof(int) * w * h * cmodel_components(color_model));
116                 }
117         }
118         else
119         {
120                 history = new VFrame*[config.frames];
121                 for(int i = 0; i < config.frames; i++)
122                         history[i] = new VFrame(0, w, h, color_model);
123                 history_size = config.frames;
124         }
129 // Cycle history
130         VFrame *temp = history[0];
131         for(int i = 0; i < history_size - 1; i++)
132                 history[i] = history[i + 1];
133         history[history_size - 1] = temp;
137 // Subtract oldest history.  Add input.  Divide by total frames.
138 #define AVERAGE_MACRO(type, components, max) \
139 { \
140         for(int i = 0; i < h; i++) \
141         { \
142                 int *accum_row = accumulation + i * w * components; \
143                 type *out_row = (type*)output->get_rows()[i]; \
144                 type *in_row = (type*)input->get_rows()[i]; \
145                 type *subtract_row = (type*)history[history_size - 1]->get_rows()[i]; \
147                 for(int j = 0; j < w * components; j++) \
148                 { \
149                         accum_row[j] -= subtract_row[j]; \
150                         accum_row[j] += in_row[j]; \
151                         subtract_row[j] = in_row[j]; \
152                         out_row[j] = accum_row[j] / history_size; \
153                 } \
154         } \
163         switch(input->get_color_model())
164         {
165                 case BC_RGB888:
166                 case BC_YUV888:
167                         AVERAGE_MACRO(unsigned char, 3, 0xff);
168                         break;
170                 case BC_RGBA8888:
171                 case BC_YUVA8888:
172                         AVERAGE_MACRO(unsigned char, 4, 0xff);
173                         break;
175                 case BC_RGB161616:
176                 case BC_YUV161616:
177                         AVERAGE_MACRO(uint16_t, 3, 0xffff);
178                         break;
180                 case BC_RGBA16161616:
181                 case BC_YUVA16161616:
182                         AVERAGE_MACRO(uint16_t, 4, 0xffff);
183                         break;
184         }
186 //printf("TimeAvgMain::process_realtime 2\n");
187         return 0;
192 int TimeAvgMain::load_defaults()
194         char directory[BCTEXTLEN], string[BCTEXTLEN];
195 // set the default directory
196         sprintf(directory, "%sbrightness.rc", BCASTDIR);
198 // load the defaults
199         defaults = new Defaults(directory);
200         defaults->load();
202         config.frames = defaults->get("FRAMES", config.frames);
203         return 0;
206 int TimeAvgMain::save_defaults()
208         defaults->update("FRAMES", config.frames);
209         defaults->save();
210         return 0;
213 void TimeAvgMain::load_configuration()
215         KeyFrame *prev_keyframe;
216 //printf("BlurMain::load_configuration 1\n");
218         prev_keyframe = get_prev_keyframe(get_source_position());
219         read_data(prev_keyframe);
222 void TimeAvgMain::save_data(KeyFrame *keyframe)
224         FileXML output;
226 // cause data to be stored directly in text
227         output.set_shared_string(keyframe->data, MESSAGESIZE);
228         output.tag.set_title("TIME_AVERAGE");
229         output.tag.set_property("FRAMES", config.frames);
230         output.append_tag();
231         output.terminate_string();
234 void TimeAvgMain::read_data(KeyFrame *keyframe)
236         FileXML input;
238         input.set_shared_string(keyframe->data, strlen(keyframe->data));
240         int result = 0;
242         while(!input.read_tag())
243         {
244                 if(input.tag.title_is("TIME_AVERAGE"))
245                 {
246                         config.frames = input.tag.get_property("FRAMES", config.frames);
247                 }
248         }
252 void TimeAvgMain::update_gui()
254         if(thread) 
255         {
256                 load_configuration();
257                 thread->window->lock_window();
258                 thread->window->total_frames->update(config.frames);
259                 thread->window->unlock_window();
260         }