00001 #include <math.h>
00002 #include <stdint.h>
00003 #include <string.h>
00004
00005 #include "bcdisplayinfo.h"
00006 #include "clip.h"
00007 #include "bchash.h"
00008 #include "filexml.h"
00009 #include "keyframe.h"
00010 #include "language.h"
00011 #include "loadbalance.h"
00012 #include "picon_png.h"
00013 #include "pluginvclient.h"
00014 #include "vframe.h"
00015
00016
00017
00018 class LinearBlurMain;
00019 class LinearBlurEngine;
00020
00021
00022
00023
00024
00025 class LinearBlurConfig
00026 {
00027 public:
00028 LinearBlurConfig();
00029
00030 int equivalent(LinearBlurConfig &that);
00031 void copy_from(LinearBlurConfig &that);
00032 void interpolate(LinearBlurConfig &prev,
00033 LinearBlurConfig &next,
00034 long prev_frame,
00035 long next_frame,
00036 long current_frame);
00037
00038 int radius;
00039 int steps;
00040 int angle;
00041 int r;
00042 int g;
00043 int b;
00044 int a;
00045 };
00046
00047
00048
00049 class LinearBlurSize : public BC_ISlider
00050 {
00051 public:
00052 LinearBlurSize(LinearBlurMain *plugin,
00053 int x,
00054 int y,
00055 int *output,
00056 int min,
00057 int max);
00058 int handle_event();
00059 LinearBlurMain *plugin;
00060 int *output;
00061 };
00062
00063 class LinearBlurToggle : public BC_CheckBox
00064 {
00065 public:
00066 LinearBlurToggle(LinearBlurMain *plugin,
00067 int x,
00068 int y,
00069 int *output,
00070 char *string);
00071 int handle_event();
00072 LinearBlurMain *plugin;
00073 int *output;
00074 };
00075
00076 class LinearBlurWindow : public BC_Window
00077 {
00078 public:
00079 LinearBlurWindow(LinearBlurMain *plugin, int x, int y);
00080 ~LinearBlurWindow();
00081
00082 int create_objects();
00083 int close_event();
00084
00085 LinearBlurSize *angle, *steps, *radius;
00086 LinearBlurToggle *r, *g, *b, *a;
00087 LinearBlurMain *plugin;
00088 };
00089
00090
00091
00092 PLUGIN_THREAD_HEADER(LinearBlurMain, LinearBlurThread, LinearBlurWindow)
00093
00094
00095
00096
00097 class LinearBlurLayer
00098 {
00099 public:
00100 LinearBlurLayer() {};
00101 int x, y;
00102 };
00103
00104 class LinearBlurMain : public PluginVClient
00105 {
00106 public:
00107 LinearBlurMain(PluginServer *server);
00108 ~LinearBlurMain();
00109
00110 int process_buffer(VFrame *frame,
00111 int64_t start_position,
00112 double frame_rate);
00113 int is_realtime();
00114 int load_defaults();
00115 int save_defaults();
00116 void save_data(KeyFrame *keyframe);
00117 void read_data(KeyFrame *keyframe);
00118 void update_gui();
00119 int handle_opengl();
00120
00121 PLUGIN_CLASS_MEMBERS(LinearBlurConfig, LinearBlurThread)
00122
00123 void delete_tables();
00124 VFrame *input, *output, *temp;
00125 LinearBlurEngine *engine;
00126 int **scale_y_table;
00127 int **scale_x_table;
00128 LinearBlurLayer *layer_table;
00129 int table_entries;
00130 int need_reconfigure;
00131
00132 unsigned char *accum;
00133 };
00134
00135 class LinearBlurPackage : public LoadPackage
00136 {
00137 public:
00138 LinearBlurPackage();
00139 int y1, y2;
00140 };
00141
00142 class LinearBlurUnit : public LoadClient
00143 {
00144 public:
00145 LinearBlurUnit(LinearBlurEngine *server, LinearBlurMain *plugin);
00146 void process_package(LoadPackage *package);
00147 LinearBlurEngine *server;
00148 LinearBlurMain *plugin;
00149 };
00150
00151 class LinearBlurEngine : public LoadServer
00152 {
00153 public:
00154 LinearBlurEngine(LinearBlurMain *plugin,
00155 int total_clients,
00156 int total_packages);
00157 void init_packages();
00158 LoadClient* new_client();
00159 LoadPackage* new_package();
00160 LinearBlurMain *plugin;
00161 };
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 REGISTER_PLUGIN(LinearBlurMain)
00182
00183
00184
00185 LinearBlurConfig::LinearBlurConfig()
00186 {
00187 radius = 10;
00188 angle = 0;
00189 steps = 10;
00190 r = 1;
00191 g = 1;
00192 b = 1;
00193 a = 1;
00194 }
00195
00196 int LinearBlurConfig::equivalent(LinearBlurConfig &that)
00197 {
00198 return
00199 radius == that.radius &&
00200 angle == that.angle &&
00201 steps == that.steps &&
00202 r == that.r &&
00203 g == that.g &&
00204 b == that.b &&
00205 a == that.a;
00206 }
00207
00208 void LinearBlurConfig::copy_from(LinearBlurConfig &that)
00209 {
00210 radius = that.radius;
00211 angle = that.angle;
00212 steps = that.steps;
00213 r = that.r;
00214 g = that.g;
00215 b = that.b;
00216 a = that.a;
00217 }
00218
00219 void LinearBlurConfig::interpolate(LinearBlurConfig &prev,
00220 LinearBlurConfig &next,
00221 long prev_frame,
00222 long next_frame,
00223 long current_frame)
00224 {
00225 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
00226 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
00227 this->radius = (int)(prev.radius * prev_scale + next.radius * next_scale + 0.5);
00228 this->angle = (int)(prev.angle * prev_scale + next.angle * next_scale + 0.5);
00229 this->steps = (int)(prev.steps * prev_scale + next.steps * next_scale + 0.5);
00230 r = prev.r;
00231 g = prev.g;
00232 b = prev.b;
00233 a = prev.a;
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 PLUGIN_THREAD_OBJECT(LinearBlurMain, LinearBlurThread, LinearBlurWindow)
00245
00246
00247
00248 LinearBlurWindow::LinearBlurWindow(LinearBlurMain *plugin, int x, int y)
00249 : BC_Window(plugin->gui_string,
00250 x,
00251 y,
00252 230,
00253 290,
00254 230,
00255 290,
00256 0,
00257 1)
00258 {
00259 this->plugin = plugin;
00260 }
00261
00262 LinearBlurWindow::~LinearBlurWindow()
00263 {
00264 }
00265
00266 int LinearBlurWindow::create_objects()
00267 {
00268 int x = 10, y = 10;
00269
00270 add_subwindow(new BC_Title(x, y, _("Length:")));
00271 y += 20;
00272 add_subwindow(radius = new LinearBlurSize(plugin, x, y, &plugin->config.radius, 0, 100));
00273 y += 30;
00274 add_subwindow(new BC_Title(x, y, _("Angle:")));
00275 y += 20;
00276 add_subwindow(angle = new LinearBlurSize(plugin, x, y, &plugin->config.angle, -180, 180));
00277 y += 30;
00278 add_subwindow(new BC_Title(x, y, _("Steps:")));
00279 y += 20;
00280 add_subwindow(steps = new LinearBlurSize(plugin, x, y, &plugin->config.steps, 1, 200));
00281 y += 30;
00282 add_subwindow(r = new LinearBlurToggle(plugin, x, y, &plugin->config.r, _("Red")));
00283 y += 30;
00284 add_subwindow(g = new LinearBlurToggle(plugin, x, y, &plugin->config.g, _("Green")));
00285 y += 30;
00286 add_subwindow(b = new LinearBlurToggle(plugin, x, y, &plugin->config.b, _("Blue")));
00287 y += 30;
00288 add_subwindow(a = new LinearBlurToggle(plugin, x, y, &plugin->config.a, _("Alpha")));
00289 y += 30;
00290
00291 show_window();
00292 flush();
00293 return 0;
00294 }
00295
00296 WINDOW_CLOSE_EVENT(LinearBlurWindow)
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 LinearBlurToggle::LinearBlurToggle(LinearBlurMain *plugin,
00308 int x,
00309 int y,
00310 int *output,
00311 char *string)
00312 : BC_CheckBox(x, y, *output, string)
00313 {
00314 this->plugin = plugin;
00315 this->output = output;
00316 }
00317
00318 int LinearBlurToggle::handle_event()
00319 {
00320 *output = get_value();
00321 plugin->send_configure_change();
00322 return 1;
00323 }
00324
00325
00326
00327
00328
00329
00330
00331 LinearBlurSize::LinearBlurSize(LinearBlurMain *plugin,
00332 int x,
00333 int y,
00334 int *output,
00335 int min,
00336 int max)
00337 : BC_ISlider(x, y, 0, 200, 200, min, max, *output)
00338 {
00339 this->plugin = plugin;
00340 this->output = output;
00341 }
00342 int LinearBlurSize::handle_event()
00343 {
00344 *output = get_value();
00345 plugin->send_configure_change();
00346 return 1;
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 LinearBlurMain::LinearBlurMain(PluginServer *server)
00359 : PluginVClient(server)
00360 {
00361 PLUGIN_CONSTRUCTOR_MACRO
00362 engine = 0;
00363 scale_x_table = 0;
00364 scale_y_table = 0;
00365 table_entries = 0;
00366 accum = 0;
00367 need_reconfigure = 1;
00368 temp = 0;
00369 layer_table = 0;
00370 }
00371
00372 LinearBlurMain::~LinearBlurMain()
00373 {
00374 PLUGIN_DESTRUCTOR_MACRO
00375 if(engine) delete engine;
00376 delete_tables();
00377 if(accum) delete [] accum;
00378 if(temp) delete temp;
00379 }
00380
00381 char* LinearBlurMain::plugin_title() { return N_("Linear Blur"); }
00382 int LinearBlurMain::is_realtime() { return 1; }
00383
00384
00385 NEW_PICON_MACRO(LinearBlurMain)
00386
00387 SHOW_GUI_MACRO(LinearBlurMain, LinearBlurThread)
00388
00389 SET_STRING_MACRO(LinearBlurMain)
00390
00391 RAISE_WINDOW_MACRO(LinearBlurMain)
00392
00393 LOAD_CONFIGURATION_MACRO(LinearBlurMain, LinearBlurConfig)
00394
00395 void LinearBlurMain::delete_tables()
00396 {
00397 if(scale_x_table)
00398 {
00399 for(int i = 0; i < table_entries; i++)
00400 delete [] scale_x_table[i];
00401 delete [] scale_x_table;
00402 }
00403
00404 if(scale_y_table)
00405 {
00406 for(int i = 0; i < table_entries; i++)
00407 delete [] scale_y_table[i];
00408 delete [] scale_y_table;
00409 }
00410 delete [] layer_table;
00411 layer_table = 0;
00412 scale_x_table = 0;
00413 scale_y_table = 0;
00414 table_entries = 0;
00415 }
00416
00417 int LinearBlurMain::process_buffer(VFrame *frame,
00418 int64_t start_position,
00419 double frame_rate)
00420 {
00421 need_reconfigure |= load_configuration();
00422
00423 read_frame(frame,
00424 0,
00425 get_source_position(),
00426 get_framerate(),
00427 get_use_opengl());
00428
00429
00430
00431
00432 if(need_reconfigure)
00433 {
00434 int w = frame->get_w();
00435 int h = frame->get_h();
00436 int x_offset;
00437 int y_offset;
00438 int angle = config.angle;
00439 int radius = config.radius * MIN(w, h) / 100;
00440
00441 while(angle < 0) angle += 360;
00442 switch(angle)
00443 {
00444 case 0:
00445 case 360:
00446 x_offset = radius;
00447 y_offset = 0;
00448 break;
00449 case 90:
00450 x_offset = 0;
00451 y_offset = radius;
00452 break;
00453 case 180:
00454 x_offset = radius;
00455 y_offset = 0;
00456 break;
00457 case 270:
00458 x_offset = 0;
00459 y_offset = radius;
00460 break;
00461 default:
00462 y_offset = (int)(sin((float)config.angle / 360 * 2 * M_PI) * radius);
00463 x_offset = (int)(cos((float)config.angle / 360 * 2 * M_PI) * radius);
00464 break;
00465 }
00466
00467
00468 delete_tables();
00469 scale_x_table = new int*[config.steps];
00470 scale_y_table = new int*[config.steps];
00471 table_entries = config.steps;
00472 layer_table = new LinearBlurLayer[table_entries];
00473
00474
00475
00476 for(int i = 0; i < config.steps; i++)
00477 {
00478 float fraction = (float)(i - config.steps / 2) / config.steps;
00479 int x = (int)(fraction * x_offset);
00480 int y = (int)(fraction * y_offset);
00481
00482 int *x_table;
00483 int *y_table;
00484 scale_y_table[i] = y_table = new int[h];
00485 scale_x_table[i] = x_table = new int[w];
00486
00487 layer_table[i].x = x;
00488 layer_table[i].y = y;
00489 for(int j = 0; j < h; j++)
00490 {
00491 y_table[j] = j + y;
00492 CLAMP(y_table[j], 0, h - 1);
00493 }
00494 for(int j = 0; j < w; j++)
00495 {
00496 x_table[j] = j + x;
00497 CLAMP(x_table[j], 0, w - 1);
00498 }
00499 }
00500 need_reconfigure = 0;
00501 }
00502
00503 if(get_use_opengl()) return run_opengl();
00504
00505
00506 if(!engine) engine = new LinearBlurEngine(this,
00507 get_project_smp() + 1,
00508 get_project_smp() + 1);
00509 if(!accum) accum = new unsigned char[frame->get_w() *
00510 frame->get_h() *
00511 cmodel_components(frame->get_color_model()) *
00512 MAX(sizeof(int), sizeof(float))];
00513
00514 this->input = frame;
00515 this->output = frame;
00516
00517
00518 if(!temp) temp = new VFrame(0,
00519 frame->get_w(),
00520 frame->get_h(),
00521 frame->get_color_model());
00522 temp->copy_from(frame);
00523 this->input = temp;
00524
00525
00526 bzero(accum,
00527 frame->get_w() *
00528 frame->get_h() *
00529 cmodel_components(frame->get_color_model()) *
00530 MAX(sizeof(int), sizeof(float)));
00531 engine->process_packages();
00532 return 0;
00533 }
00534
00535
00536 void LinearBlurMain::update_gui()
00537 {
00538 if(thread)
00539 {
00540 load_configuration();
00541 thread->window->lock_window();
00542 thread->window->radius->update(config.radius);
00543 thread->window->angle->update(config.angle);
00544 thread->window->steps->update(config.steps);
00545 thread->window->r->update(config.r);
00546 thread->window->g->update(config.g);
00547 thread->window->b->update(config.b);
00548 thread->window->a->update(config.a);
00549 thread->window->unlock_window();
00550 }
00551 }
00552
00553
00554 int LinearBlurMain::load_defaults()
00555 {
00556 char directory[1024], string[1024];
00557
00558 sprintf(directory, "%slinearblur.rc", BCASTDIR);
00559
00560
00561 defaults = new BC_Hash(directory);
00562 defaults->load();
00563
00564 config.radius = defaults->get("RADIUS", config.radius);
00565 config.angle = defaults->get("ANGLE", config.angle);
00566 config.steps = defaults->get("STEPS", config.steps);
00567 config.r = defaults->get("R", config.r);
00568 config.g = defaults->get("G", config.g);
00569 config.b = defaults->get("B", config.b);
00570 config.a = defaults->get("A", config.a);
00571 return 0;
00572 }
00573
00574
00575 int LinearBlurMain::save_defaults()
00576 {
00577 defaults->update("RADIUS", config.radius);
00578 defaults->update("ANGLE", config.angle);
00579 defaults->update("STEPS", config.steps);
00580 defaults->update("R", config.r);
00581 defaults->update("G", config.g);
00582 defaults->update("B", config.b);
00583 defaults->update("A", config.a);
00584 defaults->save();
00585 return 0;
00586 }
00587
00588
00589
00590 void LinearBlurMain::save_data(KeyFrame *keyframe)
00591 {
00592 FileXML output;
00593
00594
00595 output.set_shared_string(keyframe->data, MESSAGESIZE);
00596 output.tag.set_title("LINEARBLUR");
00597
00598 output.tag.set_property("RADIUS", config.radius);
00599 output.tag.set_property("ANGLE", config.angle);
00600 output.tag.set_property("STEPS", config.steps);
00601 output.tag.set_property("R", config.r);
00602 output.tag.set_property("G", config.g);
00603 output.tag.set_property("B", config.b);
00604 output.tag.set_property("A", config.a);
00605 output.append_tag();
00606 output.tag.set_title("/LINEARBLUR");
00607 output.append_tag();
00608 output.terminate_string();
00609 }
00610
00611 void LinearBlurMain::read_data(KeyFrame *keyframe)
00612 {
00613 FileXML input;
00614
00615 input.set_shared_string(keyframe->data, strlen(keyframe->data));
00616
00617 int result = 0;
00618
00619 while(!result)
00620 {
00621 result = input.read_tag();
00622
00623 if(!result)
00624 {
00625 if(input.tag.title_is("LINEARBLUR"))
00626 {
00627 config.radius = input.tag.get_property("RADIUS", config.radius);
00628 config.angle = input.tag.get_property("ANGLE", config.angle);
00629 config.steps = input.tag.get_property("STEPS", config.steps);
00630 config.r = input.tag.get_property("R", config.r);
00631 config.g = input.tag.get_property("G", config.g);
00632 config.b = input.tag.get_property("B", config.b);
00633 config.a = input.tag.get_property("A", config.a);
00634 }
00635 }
00636 }
00637 }
00638
00639 #ifdef HAVE_GL
00640 static void draw_box(float x1, float y1, float x2, float y2)
00641 {
00642 glBegin(GL_QUADS);
00643 glVertex3f(x1, y1, 0.0);
00644 glVertex3f(x2, y1, 0.0);
00645 glVertex3f(x2, y2, 0.0);
00646 glVertex3f(x1, y2, 0.0);
00647 glEnd();
00648 }
00649 #endif
00650
00651 int LinearBlurMain::handle_opengl()
00652 {
00653 #ifdef HAVE_GL
00654 get_output()->to_texture();
00655 get_output()->enable_opengl();
00656 get_output()->init_screen();
00657 get_output()->bind_texture(0);
00658
00659 int is_yuv = cmodel_is_yuv(get_output()->get_color_model());
00660 glClearColor(0.0, 0.0, 0.0, 0.0);
00661 glClear(GL_COLOR_BUFFER_BIT);
00662
00663
00664 glEnable(GL_BLEND);
00665 glBlendFunc(GL_ONE, GL_ONE);
00666 glDrawBuffer(GL_BACK);
00667 if(!config.r || !config.g || !config.b || !config.a)
00668 {
00669 glColor4f(config.r ? 0 : 1,
00670 config.g ? 0 : 1,
00671 config.b ? 0 : 1,
00672 config.a ? 0 : 1);
00673 get_output()->draw_texture();
00674 }
00675 glAccum(GL_LOAD, 1.0);
00676
00677
00678 float fraction = 1.0 / config.steps;
00679 for(int i = 0; i < config.steps; i++)
00680 {
00681 glClear(GL_COLOR_BUFFER_BIT);
00682 glColor4f(config.r ? 1 : 0,
00683 config.g ? 1 : 0,
00684 config.b ? 1 : 0,
00685 config.a ? 1 : 0);
00686
00687 int w = get_output()->get_w();
00688 int h = get_output()->get_h();
00689 get_output()->draw_texture(0,
00690 0,
00691 w,
00692 h,
00693 layer_table[i].x,
00694 get_output()->get_h() - layer_table[i].y,
00695 layer_table[i].x + w,
00696 get_output()->get_h() - layer_table[i].y - h,
00697 1);
00698
00699
00700
00701 glDisable(GL_TEXTURE_2D);
00702 if(is_yuv)
00703 {
00704 glColor4f(config.r ? 0.0 : 0,
00705 config.g ? 0.5 : 0,
00706 config.b ? 0.5 : 0,
00707 config.a ? 1.0 : 0);
00708 float center_x1 = 0.0;
00709 float center_x2 = get_output()->get_w();
00710 float project_x1 = layer_table[i].x;
00711 float project_x2 = layer_table[i].x + get_output()->get_w();
00712 float project_y1 = layer_table[i].y;
00713 float project_y2 = layer_table[i].y + get_output()->get_h();
00714 if(project_x1 > 0)
00715 {
00716 center_x1 = project_x1;
00717 draw_box(0, 0, project_x1, -get_output()->get_h());
00718 }
00719 if(project_x2 < get_output()->get_w())
00720 {
00721 center_x2 = project_x2;
00722 draw_box(project_x2, 0, get_output()->get_w(), -get_output()->get_h());
00723 }
00724 if(project_y1 > 0)
00725 {
00726 draw_box(center_x1,
00727 -get_output()->get_h(),
00728 center_x2,
00729 -get_output()->get_h() + project_y1);
00730 }
00731 if(project_y2 < get_output()->get_h())
00732 {
00733 draw_box(center_x1,
00734 -get_output()->get_h() + project_y2,
00735 center_x2,
00736 0);
00737 }
00738 }
00739
00740
00741
00742
00743 glAccum(GL_ACCUM, fraction);
00744 glEnable(GL_TEXTURE_2D);
00745 glColor4f(config.r ? 1 : 0,
00746 config.g ? 1 : 0,
00747 config.b ? 1 : 0,
00748 config.a ? 1 : 0);
00749 }
00750
00751 glDisable(GL_BLEND);
00752 glDisable(GL_TEXTURE_2D);
00753 glReadBuffer(GL_BACK);
00754 glAccum(GL_RETURN, 1.0);
00755
00756 glColor4f(1, 1, 1, 1);
00757 get_output()->set_opengl_state(VFrame::SCREEN);
00758 #endif
00759 }
00760
00761
00762
00763
00764
00765
00766 LinearBlurPackage::LinearBlurPackage()
00767 : LoadPackage()
00768 {
00769 }
00770
00771
00772
00773
00774 LinearBlurUnit::LinearBlurUnit(LinearBlurEngine *server,
00775 LinearBlurMain *plugin)
00776 : LoadClient(server)
00777 {
00778 this->plugin = plugin;
00779 this->server = server;
00780 }
00781
00782
00783 #define BLEND_LAYER(COMPONENTS, TYPE, TEMP, MAX, DO_YUV) \
00784 { \
00785 const int chroma_offset = (DO_YUV ? ((MAX + 1) / 2) : 0); \
00786 for(int j = pkg->y1; j < pkg->y2; j++) \
00787 { \
00788 TEMP *out_row = (TEMP*)plugin->accum + COMPONENTS * w * j; \
00789 int in_y = y_table[j]; \
00790 \
00791 \
00792 TYPE *in_row = (TYPE*)plugin->input->get_rows()[in_y]; \
00793 for(int k = 0; k < w; k++) \
00794 { \
00795 int in_x = x_table[k]; \
00796 \
00797 int in_offset = in_x * COMPONENTS; \
00798 *out_row++ += in_row[in_offset]; \
00799 if(DO_YUV) \
00800 { \
00801 *out_row++ += in_row[in_offset + 1]; \
00802 *out_row++ += in_row[in_offset + 2]; \
00803 } \
00804 else \
00805 { \
00806 *out_row++ += in_row[in_offset + 1]; \
00807 *out_row++ += in_row[in_offset + 2]; \
00808 } \
00809 if(COMPONENTS == 4) \
00810 *out_row++ += in_row[in_offset + 3]; \
00811 } \
00812 } \
00813 \
00814 \
00815 if(i == plugin->config.steps - 1) \
00816 { \
00817 for(int j = pkg->y1; j < pkg->y2; j++) \
00818 { \
00819 TEMP *in_row = (TEMP*)plugin->accum + COMPONENTS * w * j; \
00820 TYPE *in_backup = (TYPE*)plugin->input->get_rows()[j]; \
00821 TYPE *out_row = (TYPE*)plugin->output->get_rows()[j]; \
00822 for(int k = 0; k < w; k++) \
00823 { \
00824 if(do_r) \
00825 { \
00826 *out_row++ = (*in_row++ * fraction) / 0x10000; \
00827 in_backup++; \
00828 } \
00829 else \
00830 { \
00831 *out_row++ = *in_backup++; \
00832 in_row++; \
00833 } \
00834 \
00835 if(DO_YUV) \
00836 { \
00837 if(do_g) \
00838 { \
00839 *out_row++ = (*in_row++ * fraction) / 0x10000; \
00840 in_backup++; \
00841 } \
00842 else \
00843 { \
00844 *out_row++ = *in_backup++; \
00845 in_row++; \
00846 } \
00847 \
00848 if(do_b) \
00849 { \
00850 *out_row++ = (*in_row++ * fraction) / 0x10000; \
00851 in_backup++; \
00852 } \
00853 else \
00854 { \
00855 *out_row++ = *in_backup++; \
00856 in_row++; \
00857 } \
00858 } \
00859 else \
00860 { \
00861 if(do_g) \
00862 { \
00863 *out_row++ = (*in_row++ * fraction) / 0x10000; \
00864 in_backup++; \
00865 } \
00866 else \
00867 { \
00868 *out_row++ = *in_backup++; \
00869 in_row++; \
00870 } \
00871 \
00872 if(do_b) \
00873 { \
00874 *out_row++ = (*in_row++ * fraction) / 0x10000; \
00875 in_backup++; \
00876 } \
00877 else \
00878 { \
00879 *out_row++ = *in_backup++; \
00880 in_row++; \
00881 } \
00882 } \
00883 \
00884 if(COMPONENTS == 4) \
00885 { \
00886 if(do_a) \
00887 { \
00888 *out_row++ = (*in_row++ * fraction) / 0x10000; \
00889 in_backup++; \
00890 } \
00891 else \
00892 { \
00893 *out_row++ = *in_backup++; \
00894 in_row++; \
00895 } \
00896 } \
00897 } \
00898 } \
00899 } \
00900 }
00901
00902 void LinearBlurUnit::process_package(LoadPackage *package)
00903 {
00904 LinearBlurPackage *pkg = (LinearBlurPackage*)package;
00905 int h = plugin->output->get_h();
00906 int w = plugin->output->get_w();
00907
00908 int fraction = 0x10000 / plugin->config.steps;
00909 int do_r = plugin->config.r;
00910 int do_g = plugin->config.g;
00911 int do_b = plugin->config.b;
00912 int do_a = plugin->config.a;
00913 for(int i = 0; i < plugin->config.steps; i++)
00914 {
00915 int *x_table = plugin->scale_x_table[i];
00916 int *y_table = plugin->scale_y_table[i];
00917
00918 switch(plugin->input->get_color_model())
00919 {
00920 case BC_RGB_FLOAT:
00921 BLEND_LAYER(3, float, float, 1, 0)
00922 break;
00923 case BC_RGB888:
00924 BLEND_LAYER(3, uint8_t, int, 0xff, 0)
00925 break;
00926 case BC_RGBA_FLOAT:
00927 BLEND_LAYER(4, float, float, 1, 0)
00928 break;
00929 case BC_RGBA8888:
00930 BLEND_LAYER(4, uint8_t, int, 0xff, 0)
00931 break;
00932 case BC_RGB161616:
00933 BLEND_LAYER(3, uint16_t, int, 0xffff, 0)
00934 break;
00935 case BC_RGBA16161616:
00936 BLEND_LAYER(4, uint16_t, int, 0xffff, 0)
00937 break;
00938 case BC_YUV888:
00939 BLEND_LAYER(3, uint8_t, int, 0xff, 1)
00940 break;
00941 case BC_YUVA8888:
00942 BLEND_LAYER(4, uint8_t, int, 0xff, 1)
00943 break;
00944 case BC_YUV161616:
00945 BLEND_LAYER(3, uint16_t, int, 0xffff, 1)
00946 break;
00947 case BC_YUVA16161616:
00948 BLEND_LAYER(4, uint16_t, int, 0xffff, 1)
00949 break;
00950 }
00951 }
00952 }
00953
00954
00955
00956
00957
00958
00959 LinearBlurEngine::LinearBlurEngine(LinearBlurMain *plugin,
00960 int total_clients,
00961 int total_packages)
00962 : LoadServer(total_clients, total_packages)
00963 {
00964 this->plugin = plugin;
00965 }
00966
00967 void LinearBlurEngine::init_packages()
00968 {
00969 for(int i = 0; i < get_total_packages(); i++)
00970 {
00971 LinearBlurPackage *package = (LinearBlurPackage*)get_package(i);
00972 package->y1 = plugin->output->get_h() * i / get_total_packages();
00973 package->y2 = plugin->output->get_h() * (i + 1) / get_total_packages();
00974 }
00975 }
00976
00977 LoadClient* LinearBlurEngine::new_client()
00978 {
00979 return new LinearBlurUnit(this, plugin);
00980 }
00981
00982 LoadPackage* LinearBlurEngine::new_package()
00983 {
00984 return new LinearBlurPackage;
00985 }
00986
00987
00988
00989
00990