00001 #include "bcdisplayinfo.h"
00002 #include "clip.h"
00003 #include "colormodels.h"
00004 #include "filexml.h"
00005 #include "aggregated.h"
00006 #include "language.h"
00007 #include "picon_png.h"
00008 #include "interpolate.h"
00009
00010 #include <stdio.h>
00011 #include <string.h>
00012
00013
00014 REGISTER_PLUGIN(InterpolatePixelsMain)
00015
00016
00017
00018 PLUGIN_THREAD_OBJECT(InterpolatePixelsMain,
00019 InterpolatePixelsThread,
00020 InterpolatePixelsWindow)
00021
00022
00023
00024 InterpolatePixelsOffset::InterpolatePixelsOffset(InterpolatePixelsWindow *window,
00025 int x,
00026 int y,
00027 int *output)
00028 : BC_ISlider(x,
00029 y,
00030 0,
00031 50,
00032 50,
00033 0,
00034 1,
00035 *output,
00036 0)
00037 {
00038 this->window = window;
00039 this->output = output;
00040 }
00041
00042 InterpolatePixelsOffset::~InterpolatePixelsOffset()
00043 {
00044 }
00045
00046 int InterpolatePixelsOffset::handle_event()
00047 {
00048 *output = get_value();
00049 window->client->send_configure_change();
00050 return 1;
00051 }
00052
00053
00054
00055
00056
00057
00058 InterpolatePixelsWindow::InterpolatePixelsWindow(InterpolatePixelsMain *client, int x, int y)
00059 : BC_Window(client->gui_string,
00060 x,
00061 y,
00062 200,
00063 100,
00064 200,
00065 100,
00066 0,
00067 0,
00068 1)
00069 {
00070 this->client = client;
00071 }
00072
00073 InterpolatePixelsWindow::~InterpolatePixelsWindow()
00074 {
00075 }
00076
00077 int InterpolatePixelsWindow::create_objects()
00078 {
00079 int x = 10, y = 10;
00080
00081 BC_Title *title;
00082 add_tool(title = new BC_Title(x, y, _("X Offset:")));
00083 add_tool(x_offset = new InterpolatePixelsOffset(this,
00084 x + title->get_w() + 5,
00085 y,
00086 &client->config.x));
00087 y += MAX(x_offset->get_h(), title->get_h()) + 5;
00088 add_tool(title = new BC_Title(x, y, _("Y Offset:")));
00089 add_tool(y_offset = new InterpolatePixelsOffset(this,
00090 x + title->get_w() + 5,
00091 y,
00092 &client->config.y));
00093 y += MAX(y_offset->get_h(), title->get_h()) + 5;
00094
00095 show_window();
00096 return 0;
00097 }
00098
00099
00100 WINDOW_CLOSE_EVENT(InterpolatePixelsWindow)
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 InterpolatePixelsConfig::InterpolatePixelsConfig()
00114 {
00115 x = 0;
00116 y = 0;
00117 }
00118
00119 int InterpolatePixelsConfig::equivalent(InterpolatePixelsConfig &that)
00120 {
00121 return x == that.x && y == that.y;
00122 }
00123
00124 void InterpolatePixelsConfig::copy_from(InterpolatePixelsConfig &that)
00125 {
00126 x = that.x;
00127 y = that.y;
00128 }
00129
00130 void InterpolatePixelsConfig::interpolate(InterpolatePixelsConfig &prev,
00131 InterpolatePixelsConfig &next,
00132 int64_t prev_position,
00133 int64_t next_position,
00134 int64_t current_position)
00135 {
00136 this->x = prev.x;
00137 this->y = prev.y;
00138 }
00139
00140
00141
00142
00143
00144
00145 InterpolatePixelsMain::InterpolatePixelsMain(PluginServer *server)
00146 : PluginVClient(server)
00147 {
00148 PLUGIN_CONSTRUCTOR_MACRO
00149 engine = 0;
00150 }
00151
00152 InterpolatePixelsMain::~InterpolatePixelsMain()
00153 {
00154 PLUGIN_DESTRUCTOR_MACRO
00155 delete engine;
00156 }
00157
00158 char* InterpolatePixelsMain::plugin_title() { return N_("Interpolate Pixels"); }
00159 int InterpolatePixelsMain::is_realtime() { return 1; }
00160
00161
00162 SHOW_GUI_MACRO(InterpolatePixelsMain, InterpolatePixelsThread)
00163
00164 SET_STRING_MACRO(InterpolatePixelsMain)
00165
00166 RAISE_WINDOW_MACRO(InterpolatePixelsMain)
00167
00168 NEW_PICON_MACRO(InterpolatePixelsMain)
00169
00170 void InterpolatePixelsMain::update_gui()
00171 {
00172 if(thread)
00173 {
00174 int changed = load_configuration();
00175 if(changed)
00176 {
00177 thread->window->lock_window("InterpolatePixelsMain::update_gui");
00178 thread->window->x_offset->update(config.x);
00179 thread->window->y_offset->update(config.y);
00180 thread->window->unlock_window();
00181 }
00182 }
00183 }
00184
00185 int InterpolatePixelsMain::load_defaults()
00186 {
00187 char directory[1024], string[1024];
00188
00189 sprintf(directory, "%sinterpolatepixels.rc", BCASTDIR);
00190
00191
00192 defaults = new BC_Hash(directory);
00193 defaults->load();
00194 config.x = defaults->get("X", config.x);
00195 config.y = defaults->get("Y", config.y);
00196
00197 return 0;
00198 }
00199
00200 int InterpolatePixelsMain::save_defaults()
00201 {
00202 defaults->update("X", config.x);
00203 defaults->update("Y", config.y);
00204 defaults->save();
00205 return 0;
00206 }
00207
00208 LOAD_CONFIGURATION_MACRO(InterpolatePixelsMain, InterpolatePixelsConfig)
00209
00210
00211 void InterpolatePixelsMain::save_data(KeyFrame *keyframe)
00212 {
00213 FileXML output;
00214
00215
00216 output.set_shared_string(keyframe->data, MESSAGESIZE);
00217 output.tag.set_title("INTERPOLATEPIXELS");
00218 output.tag.set_property("X", config.x);
00219 output.tag.set_property("Y", config.y);
00220 output.append_tag();
00221 output.tag.set_title("/INTERPOLATEPIXELS");
00222 output.append_tag();
00223 output.terminate_string();
00224 }
00225
00226 void InterpolatePixelsMain::read_data(KeyFrame *keyframe)
00227 {
00228 FileXML input;
00229
00230 input.set_shared_string(keyframe->data, strlen(keyframe->data));
00231
00232 int result = 0;
00233 float new_threshold;
00234
00235 while(!result)
00236 {
00237 result = input.read_tag();
00238
00239 if(!result)
00240 {
00241 if(input.tag.title_is("INTERPOLATEPIXELS"))
00242 {
00243 config.x = input.tag.get_property("X", config.x);
00244 config.y = input.tag.get_property("Y", config.y);
00245 }
00246 }
00247 }
00248 }
00249
00250
00251
00252 int InterpolatePixelsMain::process_buffer(VFrame *frame,
00253 int64_t start_position,
00254 double frame_rate)
00255 {
00256 load_configuration();
00257
00258
00259 frame->get_params()->update("INTERPOLATEPIXELS_X", config.x);
00260 frame->get_params()->update("INTERPOLATEPIXELS_Y", config.y);
00261
00262 read_frame(frame,
00263 0,
00264 start_position,
00265 frame_rate,
00266 get_use_opengl());
00267
00268
00269 if(get_use_opengl())
00270 {
00271
00272 if(next_effect_is("Gamma") ||
00273 next_effect_is("Histogram") ||
00274 next_effect_is("Color Balance"))
00275 return 0;
00276
00277
00278 return run_opengl();
00279 }
00280
00281
00282 if(get_output()->get_color_model() != BC_RGB_FLOAT &&
00283 get_output()->get_color_model() != BC_RGBA_FLOAT)
00284 {
00285 printf("InterpolatePixelsMain::process_buffer: only supports float colormodels\n");
00286 return 1;
00287 }
00288
00289 new_temp(frame->get_w(), frame->get_h(), frame->get_color_model());
00290 get_temp()->copy_from(frame);
00291 if(!engine)
00292 engine = new InterpolatePixelsEngine(this);
00293 engine->process_packages();
00294
00295 return 0;
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305 int InterpolatePixelsMain::handle_opengl()
00306 {
00307 printf("InterpolatePixelsMain::handle_opengl\n");
00308 #ifdef HAVE_GL
00309
00310
00311 get_output()->to_texture();
00312 get_output()->enable_opengl();
00313
00314 char *shader_stack[] = { 0, 0, 0 };
00315 int current_shader = 0;
00316 INTERPOLATE_COMPILE(shader_stack, current_shader)
00317 unsigned int frag = VFrame::make_shader(0,
00318 shader_stack[0],
00319 0);
00320 if(frag > 0)
00321 {
00322 glUseProgram(frag);
00323 glUniform1i(glGetUniformLocation(frag, "tex"), 0);
00324 INTERPOLATE_UNIFORMS(frag)
00325 }
00326
00327
00328 get_output()->init_screen();
00329 get_output()->bind_texture(0);
00330 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00331 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00332
00333
00334 get_output()->draw_texture();
00335 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00336 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00337 glUseProgram(0);
00338 get_output()->set_opengl_state(VFrame::SCREEN);
00339
00340 #endif
00341 return 0;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 InterpolatePixelsPackage::InterpolatePixelsPackage()
00357 : LoadPackage()
00358 {
00359
00360 }
00361
00362
00363
00364
00365
00366
00367 InterpolatePixelsUnit::InterpolatePixelsUnit(InterpolatePixelsEngine *server, InterpolatePixelsMain *plugin)
00368 : LoadClient(server)
00369 {
00370 this->plugin = plugin;
00371 this->server = server;
00372 }
00373
00374 void InterpolatePixelsUnit::process_package(LoadPackage *package)
00375 {
00376 InterpolatePixelsPackage *pkg = (InterpolatePixelsPackage*)package;
00377 int h = plugin->get_temp()->get_h();
00378 int w = plugin->get_temp()->get_w();
00379 int pattern_offset_x = plugin->config.x;
00380 int pattern_offset_y = plugin->config.y;
00381 int y1 = pkg->y1;
00382 int y2 = pkg->y2;
00383 int components = cmodel_components(plugin->get_output()->get_color_model());
00384 float color_matrix[9];
00385 memcpy(color_matrix, server->color_matrix, sizeof(color_matrix));
00386
00387 y1 = MAX(y1, 1);
00388 y2 = MIN(y2, h - 1);
00389
00390
00391 for(int i = y1; i < y2; i++)
00392 {
00393 int pattern_coord_y = (i - pattern_offset_y) % 2;
00394 float *prev_row = (float*)plugin->get_temp()->get_rows()[i - 1];
00395 float *current_row = (float*)plugin->get_temp()->get_rows()[i];
00396 float *next_row = (float*)plugin->get_temp()->get_rows()[i + 1];
00397 float *out_row = (float*)plugin->get_output()->get_rows()[i];
00398
00399 prev_row += components;
00400 current_row += components;
00401 next_row += components;
00402 out_row += components;
00403 float r;
00404 float g;
00405 float b;
00406 #undef RED
00407 #define RED 0
00408 #undef GREEN
00409 #define GREEN 1
00410 #undef BLUE
00411 #define BLUE 2
00412 if(pattern_coord_y == 0)
00413 {
00414 for(int j = 1; j < w - 1; j++)
00415 {
00416 int pattern_coord_x = (j - pattern_offset_x) % 2;
00417
00418 if(pattern_coord_x == 0)
00419 {
00420 r = (prev_row[RED] + next_row[RED]) / 2;
00421 g = current_row[GREEN];
00422 b = (current_row[-components + BLUE] + current_row[components + BLUE]) / 2;
00423 }
00424 else
00425
00426 {
00427 r = (prev_row[-components + RED] +
00428 prev_row[components + RED] +
00429 next_row[-components + RED] +
00430 next_row[components + RED]) / 4;
00431 g = (current_row[-components + GREEN] +
00432 prev_row[GREEN] +
00433 current_row[components + GREEN] +
00434 next_row[GREEN]) / 4;
00435 b = current_row[BLUE];
00436 }
00437
00438 out_row[0] = r * color_matrix[0] + g * color_matrix[1] + b * color_matrix[2];
00439 out_row[1] = r * color_matrix[3] + g * color_matrix[4] + b * color_matrix[5];
00440 out_row[2] = r * color_matrix[6] + g * color_matrix[7] + b * color_matrix[8];
00441 prev_row += components;
00442 current_row += components;
00443 next_row += components;
00444 out_row += components;
00445 }
00446 }
00447 else
00448 {
00449 for(int j = 1; j < w - 1; j++)
00450 {
00451 int pattern_coord_x = (j - pattern_offset_x) % 2;
00452
00453 if(pattern_coord_x == 0)
00454 {
00455 r = current_row[RED];
00456 g = (current_row[-components + GREEN] +
00457 prev_row[GREEN] +
00458 current_row[components + GREEN] +
00459 next_row[GREEN]) / 4;
00460 b = (prev_row[-components + BLUE] +
00461 prev_row[components + BLUE] +
00462 next_row[-components + BLUE] +
00463 next_row[components + BLUE]) / 4;
00464 }
00465 else
00466
00467 {
00468 float r = (current_row[-components + RED] + current_row[components + RED]) / 2;
00469 float g = current_row[GREEN];
00470 float b = (prev_row[BLUE] + next_row[BLUE]) / 2;
00471 }
00472
00473 out_row[0] = r * color_matrix[0] + g * color_matrix[1] + b * color_matrix[2];
00474 out_row[1] = r * color_matrix[3] + g * color_matrix[4] + b * color_matrix[5];
00475 out_row[2] = r * color_matrix[6] + g * color_matrix[7] + b * color_matrix[8];
00476 prev_row += components;
00477 current_row += components;
00478 next_row += components;
00479 out_row += components;
00480 }
00481 }
00482 }
00483 }
00484
00485
00486
00487
00488 InterpolatePixelsEngine::InterpolatePixelsEngine(InterpolatePixelsMain *plugin)
00489 : LoadServer(plugin->get_project_smp() + 1, plugin->get_project_smp() + 1)
00490 {
00491 this->plugin = plugin;
00492 }
00493
00494 void InterpolatePixelsEngine::init_packages()
00495 {
00496 char string[BCTEXTLEN];
00497 string[0] = 0;
00498 plugin->get_output()->get_params()->get("DCRAW_MATRIX", string);
00499 sscanf(string,
00500 "%f %f %f %f %f %f %f %f %f",
00501 &color_matrix[0],
00502 &color_matrix[1],
00503 &color_matrix[2],
00504 &color_matrix[3],
00505 &color_matrix[4],
00506 &color_matrix[5],
00507 &color_matrix[6],
00508 &color_matrix[7],
00509 &color_matrix[8]);
00510 for(int i = 0; i < get_total_packages(); i++)
00511 {
00512 InterpolatePixelsPackage *package = (InterpolatePixelsPackage*)get_package(i);
00513 package->y1 = plugin->get_temp()->get_h() * i / get_total_packages();
00514 package->y2 = plugin->get_temp()->get_h() * (i + 1) / get_total_packages();
00515 }
00516 }
00517
00518
00519 LoadClient* InterpolatePixelsEngine::new_client()
00520 {
00521 return new InterpolatePixelsUnit(this, plugin);
00522 }
00523
00524
00525 LoadPackage* InterpolatePixelsEngine::new_package()
00526 {
00527 return new InterpolatePixelsPackage;
00528 }
00529
00530