Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.1 / plugins / blurzoom / blurzoom.C
diff --git a/cinelerra-5.1/plugins/blurzoom/blurzoom.C b/cinelerra-5.1/plugins/blurzoom/blurzoom.C
new file mode 100644 (file)
index 0000000..0fa5a41
--- /dev/null
@@ -0,0 +1,474 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#include "clip.h"
+#include "bccmodels.h"
+#include "filexml.h"
+#include "language.h"
+#include "blurzoom.h"
+#include "blurzoomwindow.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+
+PluginClient* new_plugin(PluginServer *server)
+{
+       return new BlurZoomMain(server);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+BlurZoomConfig::BlurZoomConfig()
+{
+}
+
+BlurZoomMain::BlurZoomMain(PluginServer *server)
+ : PluginVClient(server)
+{
+}
+
+BlurZoomMain::~BlurZoomMain()
+{
+}
+
+char* BlurZoomMain::plugin_title() { return _("RadioacTV"); }
+int BlurZoomMain::is_realtime() { return 1; }
+
+NEW_WINDOW_MACRO(BlurZoomMain, BlurZoomWindow)
+
+
+int BlurZoomMain::load_configuration()
+{
+       return 1;
+}
+
+
+void BlurZoomMain::save_data(KeyFrame *keyframe)
+{
+}
+
+void BlurZoomMain::read_data(KeyFrame *keyframe)
+{
+}
+
+
+#define VIDEO_HWIDTH (buf_width/2)
+#define VIDEO_HHEIGHT (buf_height/2)
+
+
+#define MAGIC_THRESHOLD 40
+#define RATIO 0.95
+
+void BlurZoomMain::image_set_threshold_y(int threshold)
+{
+       y_threshold = threshold * 7; /* fake-Y value is timed by 7 */
+}
+
+
+void BlurZoomMain::set_table()
+{
+       int bits, x, y, tx, ty, xx;
+       int ptr, prevptr;
+
+       prevptr = (int)(0.5 + RATIO * (-VIDEO_HWIDTH) + VIDEO_HWIDTH);
+
+       for(xx = 0; xx < (buf_width_blocks); xx++)
+       {
+               bits = 0;
+               for(x = 0; x < 32; x++)
+               {
+                       ptr = (int)(0.5 + RATIO * (xx * 32 + x - VIDEO_HWIDTH) + VIDEO_HWIDTH);
+                       bits = bits << 1;
+                       if(ptr != prevptr)
+                               bits |= 1;
+                       prevptr = ptr;
+               }
+               blurzoomx[xx] = bits;
+       }
+
+       ty = (int)(0.5 + RATIO * (-VIDEO_HHEIGHT) + VIDEO_HHEIGHT);
+       tx = (int)(0.5 + RATIO*  (-VIDEO_HWIDTH) + VIDEO_HWIDTH);
+       xx = (int)(0.5 + RATIO *( buf_width - 1 - VIDEO_HWIDTH) + VIDEO_HWIDTH);
+       blurzoomy[0] = ty * buf_width + tx;
+       prevptr = ty * buf_width + xx;
+
+       for(y = 1; y < buf_height; y++)
+       {
+               ty = (int)(0.5 + RATIO * (y - VIDEO_HHEIGHT) + VIDEO_HHEIGHT);
+               blurzoomy[y] = ty * buf_width + tx - prevptr;
+               prevptr = ty * buf_width + xx;
+       }
+}
+
+void BlurZoomMain::make_palette()
+{
+       int i;
+
+#define DELTA (255 / (COLORS / 2 - 1))
+
+       for(i = 0; i < COLORS / 2; i++) 
+       {
+               palette_r[i] = i * DELTA;
+               palette_g[i] = i * DELTA;
+               palette_b[i] = i * DELTA;
+       }
+
+       for(i = 0; i < COLORS / 2; i++) 
+       {
+               palette_r[i + COLORS / 2] = (i * DELTA);
+               palette_g[i + COLORS / 2] = (i * DELTA);
+               palette_b[i + COLORS / 2] = 255;
+       }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+int BlurZoomMain::start_realtime()
+{
+       buf_width_blocks = project_frame_w / 32;
+       buf_width = buf_width_blocks * 32;
+       buf_height = project_frame_h;
+       buf_area = buf_width * buf_height;
+       buf_margin_left = (project_frame_w - buf_width) / 2;
+       buf_margin_right = project_frame_w - buf_width - buf_margin_left;
+       blurzoombuf = new unsigned char[buf_area * 2];
+       blurzoomx = new int[buf_width];
+       blurzoomy = new int[buf_height];
+
+       set_table();
+       make_palette();
+       
+       bzero(blurzoombuf, buf_area * 2);
+       
+       
+       background = new uint16_t[project_frame_w * project_frame_h];
+       diff = new unsigned char[project_frame_w * project_frame_h];
+       image_set_threshold_y(MAGIC_THRESHOLD);
+       
+       blurzoom_server = new BlurZoomServer(this, 1, 1);
+       return 0;
+}
+
+int BlurZoomMain::stop_realtime()
+{
+       delete blurzoom_server;
+
+
+
+
+
+       delete [] blurzoombuf;
+       delete [] blurzoomx;
+       delete [] blurzoomy;
+
+
+
+
+
+       delete [] background;
+       delete [] diff;
+
+
+
+
+       return 0;
+}
+
+int BlurZoomMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
+{
+       load_configuration();
+       this->input_ptr = input_ptr;
+       this->output_ptr = output_ptr;
+
+
+       blurzoom_server->process_packages();
+
+       return 0;
+}
+
+
+
+
+
+BlurZoomServer::BlurZoomServer(BlurZoomMain *plugin, int total_clients, total_packages)
+ : LoadServer(total_clients, get_total_packages())
+{
+       this->plugin = plugin;
+}
+
+
+LoadClient* BlurZoomServer::new_client() 
+{
+       return new BlurZoomClient(this);
+}
+
+
+
+
+LoadPackage* BlurZoomServer::new_package() 
+{ 
+       return new BlurZoomPackage; 
+}
+
+
+
+void BlurZoomServer::init_packages()
+{
+       for(int i = 0; i < get_total_packages(); i++)
+       {
+               BlurZoomPackage *package = (BlurZoomPackage*)get_package(i);
+               package->row1 = plugin->input_ptr->get_h() / get_total_packages() * i;
+               package->row2 = package->row1 + plugin->input_ptr->get_h() / get_total_packages();
+               if(i >= get_total_packages() - 1)
+                       package->row2 = plugin->input_ptr->get_h();
+       }
+}
+
+
+
+
+
+
+
+
+BlurZoomClient::BlurZoomClient(BlurZoomServer *server)
+ : LoadClient(server)
+{
+       this->plugin = server->plugin;
+}
+
+
+
+
+
+
+
+
+
+/* Background image is refreshed every frame */
+#define IMAGE_BGSUBTRACT_UPDATE_Y(result, \
+       input_rows,  \
+       type,  \
+       components) \
+{ \
+       int i; \
+       int R, G, B; \
+       type *p; \
+       int16_t *q; \
+       unsigned char *r; \
+       int v; \
+ \
+       q = (int16_t *)background; \
+       r = diff; \
+ \
+       for(i = 0; i < project_frame_h; i++)  \
+       { \
+               p = input_rows[j]; \
+ \
+               for(j = 0; j < project_frame_w; j++) \
+               { \
+                       if(sizeof(type) == 2) \
+                       { \
+                               R = p[0] >> (8 - 1); \
+                               G = p[1] >> (8 - 2); \
+                               B = p[2] >> 8; \
+                       } \
+                       else \
+                       { \
+                               R = p[0] << 1; \
+                               G = p[1] << 2; \
+                               B = p[2]; \
+                       } \
+ \
+                       v = (R + G + B) - (int)(*q); \
+                       *q = (int16_t)(R + G + B); \
+                       *r = ((v + y_threshold) >> 24) | ((y_threshold - v) >> 24); \
+ \
+                       p += components; \
+                       q++; \
+                       r++; \
+               } \
+       } \
+ \
+       result = diff; \
+}
+
+
+
+
+#define BLURZOOM_FINAL(type, components)
+{
+       for(y = 0; y < h; y++) 
+       {
+               memcpy(output_rows[y], 
+                       input_rows[y], 
+                       buf_margin_left * plugin->input_ptr->get_bytes_per_pixel());
+
+
+               for(x = 0; x < buf_width; x++)
+               {
+                       for(c = 0; c < components; c++)
+                       {
+                               a = *src++ & 0xfefeff;
+                               b = palette[*p++];
+                               a += b;
+                               b = a & 0x1010100;
+                               *dest++ = a | (b - (b >> 8));
+                       }
+               }
+
+               memcpy(output_rows[y] + project_frame_w - buf_margin_right, 
+                       input_rows[y] + project_frame_w - buf_margin_right, 
+                       buf_margin_right * plugin->input_ptr->get_bytes_per_pixel());
+       }
+}
+
+
+
+void BlurZoomClient::process_package(LoadPackage *package)
+{
+       BlurZoomPackage *local_package = (BlurZoomPackage*)package;
+       unsigned char **input_rows = plugin->input_ptr->get_rows() + local_package->row1;
+       unsigned char **output_rows = plugin->output_ptr->get_rows() + local_package->row1;
+       int w = plugin->input_ptr->get_w();
+       int h = local_package->row2 - local_package->row1;
+       int x, y;
+       int a, b, c;
+       unsigned char *diff, *p;
+
+       switch(plugin->input_ptr->get_color_model())
+       {
+               case BC_RGB888:
+               case BC_YUV888:
+                       IMAGE_BGSUBTRACT_UPDATE_Y(diff, 
+                               input_rows, 
+                               uint8_t, 
+                               3);
+                       break;
+               case BC_RGBA8888:
+               case BC_YUVA8888:
+                       IMAGE_BGSUBTRACT_UPDATE_Y(diff, 
+                               input_rows, 
+                               uint8_t, 
+                               4);
+                       break;
+               case BC_RGB161616:
+               case BC_YUV161616:
+                       IMAGE_BGSUBTRACT_UPDATE_Y(diff, 
+                               input_rows, 
+                               uint16_t, 
+                               3);
+                       break;
+               case BC_RGBA16161616:
+               case BC_YUVA16161616:
+                       IMAGE_BGSUBTRACT_UPDATE_Y(diff, 
+                               input_rows, 
+                               uint16_t, 
+                               4);
+                       break;
+       }
+
+
+       diff += buf_margin_left;
+       p = blurzoombuf;
+
+
+
+       for(y = 0; y < buf_height; y++)
+       {
+               for(x = 0; x < buf_width; x++)
+               {
+                       p[x] |= diff[x] >> 3;
+               }
+
+               diff += w;
+               p += buf_width;
+       }
+
+
+// Assembly language only
+       blurzoomcore();
+
+
+       p = blurzoombuf;
+
+
+
+       switch(plugin->input_ptr->get_color_model())
+       {
+               case BC_RGB888:
+               case BC_YUV888:
+                       BLURZOOM_FINAL(uint8_t, 3);
+                       break;
+               case BC_RGBA8888:
+               case BC_YUVA8888:
+                       BLURZOOM_FINAL(uint8_t, 4);
+                       break;
+               case BC_RGB161616:
+               case BC_YUV161616:
+                       BLURZOOM_FINAL(uint16_t, 3);
+                       break;
+               case BC_RGBA16161616:
+               case BC_YUVA16161616:
+                       BLURZOOM_FINAL(uint16_t, 4);
+                       break;
+       }
+
+
+
+
+}
+
+
+
+BlurZoomPackage::BlurZoomPackage()
+{
+}
+
+
+