r286: Heroine Virutal's official release 1.2.0
[cinelerra_cv/ct.git] / hvirtual / plugins / blurzoom / blurzoom.C
blobe8c87aac2ec820b6fc504740300bfd525ca34741
1 #include "clip.h"
2 #include "colormodels.h"
3 #include "filexml.h"
4 #include "picon_png.h"
5 #include "blurzoom.h"
6 #include "blurzoomwindow.h"
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <string.h>
12 #include <libintl.h>
13 #define _(String) gettext(String)
14 #define gettext_noop(String) String
15 #define N_(String) gettext_noop (String)
17 PluginClient* new_plugin(PluginServer *server)
19         return new BlurZoomMain(server);
33 BlurZoomConfig::BlurZoomConfig()
37 BlurZoomMain::BlurZoomMain(PluginServer *server)
38  : PluginVClient(server)
40         thread = 0;
41         defaults = 0;
42         load_defaults();
45 BlurZoomMain::~BlurZoomMain()
47         if(thread)
48         {
49 // Set result to 0 to indicate a server side close
50                 thread->window->set_done(0);
51                 thread->completion.lock();
52                 delete thread;
53         }
55         save_defaults();
56         if(defaults) delete defaults;
59 char* BlurZoomMain::plugin_title() { return N_("RadioacTV"); }
60 int BlurZoomMain::is_realtime() { return 1; }
62 VFrame* BlurZoomMain::new_picon()
64         return new VFrame(picon_png);
67 int BlurZoomMain::load_defaults()
69         return 0;
72 int BlurZoomMain::save_defaults()
74         return 0;
77 void BlurZoomMain::load_configuration()
82 void BlurZoomMain::save_data(KeyFrame *keyframe)
86 void BlurZoomMain::read_data(KeyFrame *keyframe)
91 #define VIDEO_HWIDTH (buf_width/2)
92 #define VIDEO_HHEIGHT (buf_height/2)
95 #define MAGIC_THRESHOLD 40
96 #define RATIO 0.95
98 void BlurZoomMain::image_set_threshold_y(int threshold)
100         y_threshold = threshold * 7; /* fake-Y value is timed by 7 */
104 void BlurZoomMain::set_table()
106         int bits, x, y, tx, ty, xx;
107         int ptr, prevptr;
109         prevptr = (int)(0.5 + RATIO * (-VIDEO_HWIDTH) + VIDEO_HWIDTH);
111         for(xx = 0; xx < (buf_width_blocks); xx++)
112         {
113                 bits = 0;
114                 for(x = 0; x < 32; x++)
115                 {
116                         ptr = (int)(0.5 + RATIO * (xx * 32 + x - VIDEO_HWIDTH) + VIDEO_HWIDTH);
117                         bits = bits << 1;
118                         if(ptr != prevptr)
119                                 bits |= 1;
120                         prevptr = ptr;
121                 }
122                 blurzoomx[xx] = bits;
123         }
125         ty = (int)(0.5 + RATIO * (-VIDEO_HHEIGHT) + VIDEO_HHEIGHT);
126         tx = (int)(0.5 + RATIO*  (-VIDEO_HWIDTH) + VIDEO_HWIDTH);
127         xx = (int)(0.5 + RATIO *( buf_width - 1 - VIDEO_HWIDTH) + VIDEO_HWIDTH);
128         blurzoomy[0] = ty * buf_width + tx;
129         prevptr = ty * buf_width + xx;
131         for(y = 1; y < buf_height; y++)
132         {
133                 ty = (int)(0.5 + RATIO * (y - VIDEO_HHEIGHT) + VIDEO_HHEIGHT);
134                 blurzoomy[y] = ty * buf_width + tx - prevptr;
135                 prevptr = ty * buf_width + xx;
136         }
139 void BlurZoomMain::make_palette()
141         int i;
143 #define DELTA (255 / (COLORS / 2 - 1))
145         for(i = 0; i < COLORS / 2; i++) 
146         {
147                 palette_r[i] = i * DELTA;
148                 palette_g[i] = i * DELTA;
149                 palette_b[i] = i * DELTA;
150         }
152         for(i = 0; i < COLORS / 2; i++) 
153         {
154                 palette_r[i + COLORS / 2] = (i * DELTA);
155                 palette_g[i + COLORS / 2] = (i * DELTA);
156                 palette_b[i + COLORS / 2] = 255;
157         }
178 int BlurZoomMain::start_realtime()
180         buf_width_blocks = project_frame_w / 32;
181         buf_width = buf_width_blocks * 32;
182         buf_height = project_frame_h;
183         buf_area = buf_width * buf_height;
184         buf_margin_left = (project_frame_w - buf_width) / 2;
185         buf_margin_right = project_frame_w - buf_width - buf_margin_left;
186         blurzoombuf = new unsigned char[buf_area * 2];
187         blurzoomx = new int[buf_width];
188         blurzoomy = new int[buf_height];
190         set_table();
191         make_palette();
192         
193         bzero(blurzoombuf, buf_area * 2);
194         
195         
196         background = new uint16_t[project_frame_w * project_frame_h];
197         diff = new unsigned char[project_frame_w * project_frame_h];
198         image_set_threshold_y(MAGIC_THRESHOLD);
199         
200         blurzoom_server = new BlurZoomServer(this, 1, 1);
201         return 0;
204 int BlurZoomMain::stop_realtime()
206         delete blurzoom_server;
212         delete [] blurzoombuf;
213         delete [] blurzoomx;
214         delete [] blurzoomy;
220         delete [] background;
221         delete [] diff;
226         return 0;
229 int BlurZoomMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
231         load_configuration();
232         this->input_ptr = input_ptr;
233         this->output_ptr = output_ptr;
236         blurzoom_server->process_packages();
238         return 0;
241 int BlurZoomMain::show_gui()
243         load_configuration();
244         thread = new BlurZoomThread(this);
245         thread->start();
246         return 0;
249 int BlurZoomMain::set_string()
251         if(thread) thread->window->set_title(gui_string);
252         return 0;
255 void BlurZoomMain::raise_window()
257         if(thread)
258         {
259                 thread->window->raise_window();
260                 thread->window->flush();
261         }
267 BlurZoomServer::BlurZoomServer(BlurZoomMain *plugin, int total_clients, int total_packages)
268  : LoadServer(total_clients, total_packages)
270         this->plugin = plugin;
274 LoadClient* BlurZoomServer::new_client() 
276         return new BlurZoomClient(this);
282 LoadPackage* BlurZoomServer::new_package() 
284         return new BlurZoomPackage; 
289 void BlurZoomServer::init_packages()
291         for(int i = 0; i < total_packages; i++)
292         {
293                 BlurZoomPackage *package = (BlurZoomPackage*)packages[i];
294                 package->row1 = plugin->input_ptr->get_h() / total_packages * i;
295                 package->row2 = package->row1 + plugin->input_ptr->get_h() / total_packages;
296                 if(i >= total_packages - 1)
297                         package->row2 = plugin->input_ptr->get_h();
298         }
308 BlurZoomClient::BlurZoomClient(BlurZoomServer *server)
309  : LoadClient(server)
311         this->plugin = server->plugin;
322 /* Background image is refreshed every frame */
323 #define IMAGE_BGSUBTRACT_UPDATE_Y(result, \
324         input_rows,  \
325         type,  \
326         components) \
327 { \
328         int i; \
329         int R, G, B; \
330         type *p; \
331         int16_t *q; \
332         unsigned char *r; \
333         int v; \
335         q = (int16_t *)background; \
336         r = diff; \
338         for(i = 0; i < project_frame_h; i++)  \
339         { \
340                 p = input_rows[j]; \
342                 for(j = 0; j < project_frame_w; j++) \
343                 { \
344                         if(sizeof(type) == 2) \
345                         { \
346                                 R = p[0] >> (8 - 1); \
347                                 G = p[1] >> (8 - 2); \
348                                 B = p[2] >> 8; \
349                         } \
350                         else \
351                         { \
352                                 R = p[0] << 1; \
353                                 G = p[1] << 2; \
354                                 B = p[2]; \
355                         } \
357                         v = (R + G + B) - (int)(*q); \
358                         *q = (int16_t)(R + G + B); \
359                         *r = ((v + y_threshold) >> 24) | ((y_threshold - v) >> 24); \
361                         p += components; \
362                         q++; \
363                         r++; \
364                 } \
365         } \
367         result = diff; \
373 #define BLURZOOM_FINAL(type, components)
375         for(y = 0; y < h; y++) 
376         {
377                 memcpy(output_rows[y], 
378                         input_rows[y], 
379                         buf_margin_left * plugin->input_ptr->get_bytes_per_pixel());
382                 for(x = 0; x < buf_width; x++)
383                 {
384                         for(c = 0; c < components; c++)
385                         {
386                                 a = *src++ & 0xfefeff;
387                                 b = palette[*p++];
388                                 a += b;
389                                 b = a & 0x1010100;
390                                 *dest++ = a | (b - (b >> 8));
391                         }
392                 }
394                 memcpy(output_rows[y] + project_frame_w - buf_margin_right, 
395                         input_rows[y] + project_frame_w - buf_margin_right, 
396                         buf_margin_right * plugin->input_ptr->get_bytes_per_pixel());
397         }
402 void BlurZoomClient::process_package(LoadPackage *package)
404         BlurZoomPackage *local_package = (BlurZoomPackage*)package;
405         unsigned char **input_rows = plugin->input_ptr->get_rows() + local_package->row1;
406         unsigned char **output_rows = plugin->output_ptr->get_rows() + local_package->row1;
407         int w = plugin->input_ptr->get_w();
408         int h = local_package->row2 - local_package->row1;
409         int x, y;
410         int a, b, c;
411         unsigned char *diff, *p;
413         switch(plugin->input_ptr->get_color_model())
414         {
415                 case BC_RGB888:
416                 case BC_YUV888:
417                         IMAGE_BGSUBTRACT_UPDATE_Y(diff, 
418                                 input_rows, 
419                                 uint8_t, 
420                                 3);
421                         break;
422                 case BC_RGBA8888:
423                 case BC_YUVA8888:
424                         IMAGE_BGSUBTRACT_UPDATE_Y(diff, 
425                                 input_rows, 
426                                 uint8_t, 
427                                 4);
428                         break;
429                 case BC_RGB161616:
430                 case BC_YUV161616:
431                         IMAGE_BGSUBTRACT_UPDATE_Y(diff, 
432                                 input_rows, 
433                                 uint16_t, 
434                                 3);
435                         break;
436                 case BC_RGBA16161616:
437                 case BC_YUVA16161616:
438                         IMAGE_BGSUBTRACT_UPDATE_Y(diff, 
439                                 input_rows, 
440                                 uint16_t, 
441                                 4);
442                         break;
443         }
446         diff += buf_margin_left;
447         p = blurzoombuf;
451         for(y = 0; y < buf_height; y++)
452         {
453                 for(x = 0; x < buf_width; x++)
454                 {
455                         p[x] |= diff[x] >> 3;
456                 }
458                 diff += w;
459                 p += buf_width;
460         }
463 // Assembly language only
464         blurzoomcore();
467         p = blurzoombuf;
471         switch(plugin->input_ptr->get_color_model())
472         {
473                 case BC_RGB888:
474                 case BC_YUV888:
475                         BLURZOOM_FINAL(uint8_t, 3);
476                         break;
477                 case BC_RGBA8888:
478                 case BC_YUVA8888:
479                         BLURZOOM_FINAL(uint8_t, 4);
480                         break;
481                 case BC_RGB161616:
482                 case BC_YUV161616:
483                         BLURZOOM_FINAL(uint16_t, 3);
484                         break;
485                 case BC_RGBA16161616:
486                 case BC_YUVA16161616:
487                         BLURZOOM_FINAL(uint16_t, 4);
488                         break;
489         }
498 BlurZoomPackage::BlurZoomPackage()