mask xy scale, mask boundary only overlay, fix 8 char mask nm bug, rework maskgui...
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / blurzoom / blurzoom.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "clip.h"
23 #include "bccmodels.h"
24 #include "filexml.h"
25 #include "language.h"
26 #include "blurzoom.h"
27 #include "blurzoomwindow.h"
28
29 #include <stdint.h>
30 #include <stdio.h>
31 #include <string.h>
32
33
34 PluginClient* new_plugin(PluginServer *server)
35 {
36         return new BlurZoomMain(server);
37 }
38
39
40
41
42
43
44
45
46
47
48
49
50 BlurZoomConfig::BlurZoomConfig()
51 {
52 }
53
54 BlurZoomMain::BlurZoomMain(PluginServer *server)
55  : PluginVClient(server)
56 {
57 }
58
59 BlurZoomMain::~BlurZoomMain()
60 {
61 }
62
63 char* BlurZoomMain::plugin_title() { return N_("RadioacTV"); }
64 int BlurZoomMain::is_realtime() { return 1; }
65
66 NEW_WINDOW_MACRO(BlurZoomMain, BlurZoomWindow)
67
68
69 int BlurZoomMain::load_configuration()
70 {
71         return 1;
72 }
73
74
75 void BlurZoomMain::save_data(KeyFrame *keyframe)
76 {
77 }
78
79 void BlurZoomMain::read_data(KeyFrame *keyframe)
80 {
81 }
82
83
84 #define VIDEO_HWIDTH (buf_width/2)
85 #define VIDEO_HHEIGHT (buf_height/2)
86
87
88 #define MAGIC_THRESHOLD 40
89 #define RATIO 0.95
90
91 void BlurZoomMain::image_set_threshold_y(int threshold)
92 {
93         y_threshold = threshold * 7; /* fake-Y value is timed by 7 */
94 }
95
96
97 void BlurZoomMain::set_table()
98 {
99         int bits, x, y, tx, ty, xx;
100         int ptr, prevptr;
101
102         prevptr = (int)(0.5 + RATIO * (-VIDEO_HWIDTH) + VIDEO_HWIDTH);
103
104         for(xx = 0; xx < (buf_width_blocks); xx++)
105         {
106                 bits = 0;
107                 for(x = 0; x < 32; x++)
108                 {
109                         ptr = (int)(0.5 + RATIO * (xx * 32 + x - VIDEO_HWIDTH) + VIDEO_HWIDTH);
110                         bits = bits << 1;
111                         if(ptr != prevptr)
112                                 bits |= 1;
113                         prevptr = ptr;
114                 }
115                 blurzoomx[xx] = bits;
116         }
117
118         ty = (int)(0.5 + RATIO * (-VIDEO_HHEIGHT) + VIDEO_HHEIGHT);
119         tx = (int)(0.5 + RATIO*  (-VIDEO_HWIDTH) + VIDEO_HWIDTH);
120         xx = (int)(0.5 + RATIO *( buf_width - 1 - VIDEO_HWIDTH) + VIDEO_HWIDTH);
121         blurzoomy[0] = ty * buf_width + tx;
122         prevptr = ty * buf_width + xx;
123
124         for(y = 1; y < buf_height; y++)
125         {
126                 ty = (int)(0.5 + RATIO * (y - VIDEO_HHEIGHT) + VIDEO_HHEIGHT);
127                 blurzoomy[y] = ty * buf_width + tx - prevptr;
128                 prevptr = ty * buf_width + xx;
129         }
130 }
131
132 void BlurZoomMain::make_palette()
133 {
134         int i;
135
136 #define DELTA (255 / (COLORS / 2 - 1))
137
138         for(i = 0; i < COLORS / 2; i++)
139         {
140                 palette_r[i] = i * DELTA;
141                 palette_g[i] = i * DELTA;
142                 palette_b[i] = i * DELTA;
143         }
144
145         for(i = 0; i < COLORS / 2; i++)
146         {
147                 palette_r[i + COLORS / 2] = (i * DELTA);
148                 palette_g[i + COLORS / 2] = (i * DELTA);
149                 palette_b[i + COLORS / 2] = 255;
150         }
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171 int BlurZoomMain::start_realtime()
172 {
173         buf_width_blocks = project_frame_w / 32;
174         buf_width = buf_width_blocks * 32;
175         buf_height = project_frame_h;
176         buf_area = buf_width * buf_height;
177         buf_margin_left = (project_frame_w - buf_width) / 2;
178         buf_margin_right = project_frame_w - buf_width - buf_margin_left;
179         blurzoombuf = new unsigned char[buf_area * 2];
180         blurzoomx = new int[buf_width];
181         blurzoomy = new int[buf_height];
182
183         set_table();
184         make_palette();
185
186         bzero(blurzoombuf, buf_area * 2);
187
188
189         background = new uint16_t[project_frame_w * project_frame_h];
190         diff = new unsigned char[project_frame_w * project_frame_h];
191         image_set_threshold_y(MAGIC_THRESHOLD);
192
193         blurzoom_server = new BlurZoomServer(this, 1, 1);
194         return 0;
195 }
196
197 int BlurZoomMain::stop_realtime()
198 {
199         delete blurzoom_server;
200
201
202
203
204
205         delete [] blurzoombuf;
206         delete [] blurzoomx;
207         delete [] blurzoomy;
208
209
210
211
212
213         delete [] background;
214         delete [] diff;
215
216
217
218
219         return 0;
220 }
221
222 int BlurZoomMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
223 {
224         load_configuration();
225         this->input_ptr = input_ptr;
226         this->output_ptr = output_ptr;
227
228
229         blurzoom_server->process_packages();
230
231         return 0;
232 }
233
234
235
236
237
238 BlurZoomServer::BlurZoomServer(BlurZoomMain *plugin, int total_clients, total_packages)
239  : LoadServer(total_clients, get_total_packages())
240 {
241         this->plugin = plugin;
242 }
243
244
245 LoadClient* BlurZoomServer::new_client()
246 {
247         return new BlurZoomClient(this);
248 }
249
250
251
252
253 LoadPackage* BlurZoomServer::new_package()
254 {
255         return new BlurZoomPackage;
256 }
257
258
259
260 void BlurZoomServer::init_packages()
261 {
262         for(int i = 0; i < get_total_packages(); i++)
263         {
264                 BlurZoomPackage *package = (BlurZoomPackage*)get_package(i);
265                 package->row1 = plugin->input_ptr->get_h() / get_total_packages() * i;
266                 package->row2 = package->row1 + plugin->input_ptr->get_h() / get_total_packages();
267                 if(i >= get_total_packages() - 1)
268                         package->row2 = plugin->input_ptr->get_h();
269         }
270 }
271
272
273
274
275
276
277
278
279 BlurZoomClient::BlurZoomClient(BlurZoomServer *server)
280  : LoadClient(server)
281 {
282         this->plugin = server->plugin;
283 }
284
285
286
287
288
289
290
291
292
293 /* Background image is refreshed every frame */
294 #define IMAGE_BGSUBTRACT_UPDATE_Y(result, \
295         input_rows,  \
296         type,  \
297         components) \
298 { \
299         int i; \
300         int R, G, B; \
301         type *p; \
302         int16_t *q; \
303         unsigned char *r; \
304         int v; \
305  \
306         q = (int16_t *)background; \
307         r = diff; \
308  \
309         for(i = 0; i < project_frame_h; i++)  \
310         { \
311                 p = input_rows[j]; \
312  \
313                 for(j = 0; j < project_frame_w; j++) \
314                 { \
315                         if(sizeof(type) == 2) \
316                         { \
317                                 R = p[0] >> (8 - 1); \
318                                 G = p[1] >> (8 - 2); \
319                                 B = p[2] >> 8; \
320                         } \
321                         else \
322                         { \
323                                 R = p[0] << 1; \
324                                 G = p[1] << 2; \
325                                 B = p[2]; \
326                         } \
327  \
328                         v = (R + G + B) - (int)(*q); \
329                         *q = (int16_t)(R + G + B); \
330                         *r = ((v + y_threshold) >> 24) | ((y_threshold - v) >> 24); \
331  \
332                         p += components; \
333                         q++; \
334                         r++; \
335                 } \
336         } \
337  \
338         result = diff; \
339 }
340
341
342
343
344 #define BLURZOOM_FINAL(type, components)
345 {
346         for(y = 0; y < h; y++)
347         {
348                 memcpy(output_rows[y],
349                         input_rows[y],
350                         buf_margin_left * plugin->input_ptr->get_bytes_per_pixel());
351
352
353                 for(x = 0; x < buf_width; x++)
354                 {
355                         for(c = 0; c < components; c++)
356                         {
357                                 a = *src++ & 0xfefeff;
358                                 b = palette[*p++];
359                                 a += b;
360                                 b = a & 0x1010100;
361                                 *dest++ = a | (b - (b >> 8));
362                         }
363                 }
364
365                 memcpy(output_rows[y] + project_frame_w - buf_margin_right,
366                         input_rows[y] + project_frame_w - buf_margin_right,
367                         buf_margin_right * plugin->input_ptr->get_bytes_per_pixel());
368         }
369 }
370
371
372
373 void BlurZoomClient::process_package(LoadPackage *package)
374 {
375         BlurZoomPackage *local_package = (BlurZoomPackage*)package;
376         unsigned char **input_rows = plugin->input_ptr->get_rows() + local_package->row1;
377         unsigned char **output_rows = plugin->output_ptr->get_rows() + local_package->row1;
378         int w = plugin->input_ptr->get_w();
379         int h = local_package->row2 - local_package->row1;
380         int x, y;
381         int a, b, c;
382         unsigned char *diff, *p;
383
384         switch(plugin->input_ptr->get_color_model())
385         {
386                 case BC_RGB888:
387                 case BC_YUV888:
388                         IMAGE_BGSUBTRACT_UPDATE_Y(diff,
389                                 input_rows,
390                                 uint8_t,
391                                 3);
392                         break;
393                 case BC_RGBA8888:
394                 case BC_YUVA8888:
395                         IMAGE_BGSUBTRACT_UPDATE_Y(diff,
396                                 input_rows,
397                                 uint8_t,
398                                 4);
399                         break;
400                 case BC_RGB161616:
401                 case BC_YUV161616:
402                         IMAGE_BGSUBTRACT_UPDATE_Y(diff,
403                                 input_rows,
404                                 uint16_t,
405                                 3);
406                         break;
407                 case BC_RGBA16161616:
408                 case BC_YUVA16161616:
409                         IMAGE_BGSUBTRACT_UPDATE_Y(diff,
410                                 input_rows,
411                                 uint16_t,
412                                 4);
413                         break;
414         }
415
416
417         diff += buf_margin_left;
418         p = blurzoombuf;
419
420
421
422         for(y = 0; y < buf_height; y++)
423         {
424                 for(x = 0; x < buf_width; x++)
425                 {
426                         p[x] |= diff[x] >> 3;
427                 }
428
429                 diff += w;
430                 p += buf_width;
431         }
432
433
434 // Assembly language only
435         blurzoomcore();
436
437
438         p = blurzoombuf;
439
440
441
442         switch(plugin->input_ptr->get_color_model())
443         {
444                 case BC_RGB888:
445                 case BC_YUV888:
446                         BLURZOOM_FINAL(uint8_t, 3);
447                         break;
448                 case BC_RGBA8888:
449                 case BC_YUVA8888:
450                         BLURZOOM_FINAL(uint8_t, 4);
451                         break;
452                 case BC_RGB161616:
453                 case BC_YUV161616:
454                         BLURZOOM_FINAL(uint16_t, 3);
455                         break;
456                 case BC_RGBA16161616:
457                 case BC_YUVA16161616:
458                         BLURZOOM_FINAL(uint16_t, 4);
459                         break;
460         }
461
462
463
464
465 }
466
467
468
469 BlurZoomPackage::BlurZoomPackage()
470 {
471 }
472
473
474