00001 #include "bcdisplayinfo.h"
00002 #include "clip.h"
00003 #include "bchash.h"
00004 #include "filexml.h"
00005 #include "denoise.h"
00006 #include "picon_png.h"
00007 #include "units.h"
00008 #include "vframe.h"
00009
00010 #include <math.h>
00011 #include <string.h>
00012
00013 #include <libintl.h>
00014 #define _(String) gettext(String)
00015 #define gettext_noop(String) String
00016 #define N_(String) gettext_noop (String)
00017
00018
00019
00020
00021 #define WINDOW_BORDER (window_size / 2)
00022 #define SGN(x) (x<0 ? -1: 1)
00023
00024
00025 REGISTER_PLUGIN(DenoiseEffect)
00026
00027
00028
00029
00030
00031 DenoiseEffect::DenoiseEffect(PluginServer *server)
00032 : PluginAClient(server)
00033 {
00034 reset();
00035 PLUGIN_CONSTRUCTOR_MACRO
00036 }
00037
00038 DenoiseEffect::~DenoiseEffect()
00039 {
00040 PLUGIN_DESTRUCTOR_MACRO
00041 delete_dsp();
00042 }
00043
00044 NEW_PICON_MACRO(DenoiseEffect)
00045
00046 LOAD_CONFIGURATION_MACRO(DenoiseEffect, DenoiseConfig)
00047
00048 SHOW_GUI_MACRO(DenoiseEffect, DenoiseThread)
00049
00050 RAISE_WINDOW_MACRO(DenoiseEffect)
00051
00052 SET_STRING_MACRO(DenoiseEffect)
00053
00054 void DenoiseEffect::delete_dsp()
00055 {
00056 if(ex_coeff_d) delete ex_coeff_d;
00057 if(ex_coeff_r) delete ex_coeff_r;
00058 if(ex_coeff_rn) delete ex_coeff_rn;
00059 if(wave_coeff_d) delete wave_coeff_d;
00060 if(wave_coeff_r) delete wave_coeff_r;
00061 if(decomp_filter) delete decomp_filter;
00062 if(recon_filter) delete recon_filter;
00063 if(input_buffer) delete [] input_buffer;
00064 if(output_buffer) delete [] output_buffer;
00065 if(dsp_in) delete [] dsp_in;
00066 if(dsp_out) delete [] dsp_out;
00067 if(dsp_iteration) delete [] dsp_iteration;
00068
00069 ex_coeff_d = 0;
00070 ex_coeff_r = 0;
00071 ex_coeff_rn = 0;
00072 wave_coeff_d = 0;
00073 wave_coeff_r = 0;
00074 decomp_filter = 0;
00075 recon_filter = 0;
00076 input_buffer = 0;
00077 output_buffer = 0;
00078 dsp_in = 0;
00079 dsp_out = 0;
00080 dsp_iteration = 0;
00081 }
00082
00083
00084 void DenoiseEffect::reset()
00085 {
00086 first_window = 1;
00087 thread = 0;
00088 ex_coeff_d = 0;
00089 ex_coeff_r = 0;
00090 ex_coeff_rn = 0;
00091 wave_coeff_d = 0;
00092 wave_coeff_r = 0;
00093 decomp_filter = 0;
00094 recon_filter = 0;
00095 input_buffer = 0;
00096 output_buffer = 0;
00097 input_size = 0;
00098 output_size = 0;
00099 input_allocation = 0;
00100 output_allocation = 0;
00101 dsp_iteration = 0;
00102 in_scale = 0;
00103 out_scale = 0;
00104 dsp_in = 0;
00105 dsp_out = 0;
00106 initialized = 0;
00107
00108
00109 alpha = 1.359803732;
00110 beta = -0.782106385;
00111 window_size = 4096;
00112 output_level = 1.0;
00113 levels = 1;
00114 iterations = 1;
00115 }
00116
00117 char* DenoiseEffect::plugin_title() { return N_("Denoise"); }
00118 int DenoiseEffect::is_realtime() { return 1; }
00119
00120
00121
00122 void DenoiseEffect::read_data(KeyFrame *keyframe)
00123 {
00124 FileXML input;
00125 input.set_shared_string(keyframe->data, strlen(keyframe->data));
00126
00127 int result = 0;
00128 while(!result)
00129 {
00130 result = input.read_tag();
00131
00132 if(!result)
00133 {
00134 if(input.tag.title_is("DENOISE"))
00135 {
00136 config.level = input.tag.get_property("LEVEL", config.level);
00137 }
00138 }
00139 }
00140 }
00141
00142 void DenoiseEffect::save_data(KeyFrame *keyframe)
00143 {
00144 FileXML output;
00145 output.set_shared_string(keyframe->data, MESSAGESIZE);
00146
00147 output.tag.set_title("DENOISE");
00148 output.tag.set_property("LEVEL", config.level);
00149 output.append_tag();
00150 output.tag.set_title("/DENOISE");
00151 output.append_tag();
00152 output.append_newline();
00153
00154 output.terminate_string();
00155 }
00156
00157 int DenoiseEffect::load_defaults()
00158 {
00159 char directory[BCTEXTLEN], string[BCTEXTLEN];
00160 sprintf(directory, "%sdenoise.rc", BCASTDIR);
00161 defaults = new BC_Hash(directory);
00162 defaults->load();
00163
00164 config.level = defaults->get("LEVEL", config.level);
00165 return 0;
00166 }
00167
00168 int DenoiseEffect::save_defaults()
00169 {
00170 char string[BCTEXTLEN];
00171
00172 defaults->update("LEVEL", config.level);
00173 defaults->save();
00174
00175 return 0;
00176 }
00177
00178 void DenoiseEffect::update_gui()
00179 {
00180 if(thread)
00181 {
00182 thread->window->lock_window();
00183 thread->window->update();
00184 thread->window->unlock_window();
00185 }
00186 }
00187
00188
00189
00190 double DenoiseEffect::dot_product(double *data, double *filter, char filtlen)
00191 {
00192 static int i;
00193 static double sum;
00194
00195 sum = 0.0;
00196 for(i = 0; i < filtlen; i++) sum += *data-- * *filter++;
00197 return sum;
00198 }
00199
00200 int DenoiseEffect::convolve_dec_2(double *input_sequence,
00201 int64_t length,
00202 double *filter,
00203 int filtlen,
00204 double *output_sequence)
00205 {
00206
00207 int i, shortlen, offset;
00208 int64_t lengthp4 = length + 4;
00209 int64_t lengthm4 = length - 4;
00210 int64_t lengthp5 = length + 5;
00211 int64_t lengthp8 = length + 8;
00212
00213 for(i = 0; (i <= lengthp8) && ((i - filtlen) <= lengthp8); i += 2)
00214 {
00215 if(i < filtlen)
00216 *output_sequence++ = dot_product(input_sequence + i, filter, i + 1);
00217 else
00218 if(i > lengthp5)
00219 {
00220 offset = i - lengthm4;
00221 shortlen = filtlen - offset;
00222 *output_sequence++ = dot_product(input_sequence + lengthp4,
00223 filter + offset, shortlen);
00224 }
00225 else
00226 *output_sequence++ = dot_product(input_sequence + i, filter, filtlen);
00227 }
00228 return 0;
00229 }
00230
00231 int64_t DenoiseEffect::decompose_branches(double *in_data,
00232 int64_t length,
00233 WaveletFilters *decomp_filter,
00234 double *out_low,
00235 double *out_high)
00236 {
00237
00238
00239 convolve_dec_2(in_data, length, decomp_filter->h, decomp_filter->length, out_low);
00240 convolve_dec_2(in_data, length, decomp_filter->g, decomp_filter->length, out_high);
00241 return (length / 2);
00242 }
00243
00244 int DenoiseEffect::wavelet_decomposition(double *in_data,
00245 int64_t in_length,
00246 double **out_data)
00247 {
00248 for(int i = 0; i < levels; i++)
00249 {
00250 in_length = decompose_branches(in_data,
00251 in_length,
00252 decomp_filter,
00253 out_data[2 * i],
00254 out_data[(2 * i) + 1]);
00255
00256 in_data = out_data[2 * i];
00257 }
00258 return 0;
00259 }
00260
00261 int DenoiseEffect::tree_copy(double **output,
00262 double **input,
00263 int length,
00264 int levels)
00265 {
00266 register int i, j, k, l, m;
00267
00268 for(i = 0, k = 1; k < levels; i++, k++)
00269 {
00270 length /= 2;
00271 l = 2 * i;
00272 m = l + 1;
00273
00274 for(j = 0; j < length + 5; j++)
00275 {
00276 output[l][j] = 0.0;
00277 output[m][j] = input[m][j];
00278 }
00279 }
00280
00281 length /= 2;
00282 l = 2 * i;
00283 m = l + 1;
00284
00285 for(j = 0; j < length + 5; j++)
00286 {
00287 output[l][j] = input[l][j];
00288 output[m][j] = input[m][j];
00289 }
00290 return 0;
00291 }
00292
00293 int DenoiseEffect::threshold(int window_size, double gammas, int levels)
00294 {
00295 int i, j;
00296 double threshold, cv, cvb, abs_coeff_r;
00297 double *coeff_r, *coeff_l;
00298 int length;
00299
00300 for(i = 0; i < levels; i++)
00301 {
00302 length = (window_size >> (i + 1)) + 5;
00303 threshold = sqrt(2 * log(length) / log(2)) * gammas / sqrt(length);
00304
00305 for(j = 0; j < length; j++)
00306 {
00307 coeff_r = &(ex_coeff_r->values[(2 * i) + 1][j]);
00308 coeff_l = &(ex_coeff_rn->values[(2 * i) + 1][j]);
00309
00310 cv = SGN(*coeff_r);
00311 abs_coeff_r = fabs(*coeff_r);
00312 cvb = abs_coeff_r - threshold;
00313 cv *= cvb;
00314
00315 if(abs_coeff_r > threshold)
00316 {
00317 *coeff_r = cv;
00318 *coeff_l = 0.0;
00319 }
00320 else
00321 {
00322 *coeff_l = *coeff_r;
00323 *coeff_r = 0.0;
00324 }
00325 }
00326 }
00327 }
00328
00329
00330 double DenoiseEffect::dot_product_even(double *data, double *filter, int filtlen)
00331 {
00332 static int i;
00333 static double sum;
00334
00335 sum = 0.0;
00336 for(i = 0; i < filtlen; i += 2) sum += *data-- * filter[i];
00337 return sum;
00338 }
00339
00340
00341 double DenoiseEffect::dot_product_odd(double *data, double *filter, int filtlen)
00342 {
00343 static int i;
00344 static double sum;
00345
00346 sum = 0.0;
00347 for(i = 1; i < filtlen; i += 2) sum += *data-- * filter[i];
00348 return sum;
00349 }
00350
00351 int DenoiseEffect::convolve_int_2(double *input_sequence,
00352 int64_t length,
00353 double *filter,
00354 int filtlen,
00355 int sum_output,
00356 double *output_sequence)
00357
00358
00359 {
00360 register int i, j;
00361 int endpoint = length + filtlen - 2;
00362
00363 if (sum_output)
00364 {
00365
00366
00367 for(i = (filtlen / 2) - 1, j = (filtlen / 2); i < endpoint; i++, j++)
00368 {
00369 *output_sequence++ += dot_product_odd(input_sequence + i, filter, filtlen);
00370 *output_sequence++ += dot_product_even(input_sequence + j, filter, filtlen);
00371 }
00372
00373 *output_sequence++ += dot_product_odd(input_sequence + i, filter, filtlen);
00374 }
00375 else
00376 {
00377
00378
00379 for(i = (filtlen / 2) - 1, j = (filtlen / 2); i < endpoint; i++, j++)
00380 {
00381 *output_sequence++ = dot_product_odd(input_sequence + i, filter, filtlen);
00382 *output_sequence++ = dot_product_even(input_sequence + j, filter, filtlen);
00383 }
00384
00385 *output_sequence++ = dot_product_odd(input_sequence + i, filter, filtlen);
00386 }
00387 return 0;
00388 }
00389
00390
00391 int64_t DenoiseEffect::reconstruct_branches(double *in_low,
00392 double *in_high,
00393 int64_t in_length,
00394 WaveletFilters *recon_filter,
00395 double *output)
00396 {
00397
00398
00399 convolve_int_2(in_low, in_length, recon_filter->h,
00400 recon_filter->length, 0, output);
00401 convolve_int_2(in_high, in_length, recon_filter->g,
00402 recon_filter->length, 1, output);
00403 return in_length * 2;
00404 }
00405
00406 int DenoiseEffect::wavelet_reconstruction(double **in_data,
00407 int64_t in_length,
00408 double *out_data)
00409 {
00410 double *output;
00411 int i;
00412
00413 in_length = in_length >> levels;
00414
00415
00416 for(i = levels - 1; i > 0; i--)
00417 {
00418 output = in_data[2 * (i - 1)];
00419 in_length = reconstruct_branches(in_data[2 * i],
00420 in_data[(2 * i) + 1],
00421 in_length,
00422 recon_filter,
00423 output);
00424 }
00425
00426
00427 reconstruct_branches(in_data[0],
00428 in_data[1],
00429 in_length,
00430 recon_filter,
00431 out_data);
00432
00433 return 0;
00434 }
00435
00436 void DenoiseEffect::process_window()
00437 {
00438 int i, j;
00439 for(j = 0; j < iterations; j++)
00440 {
00441 wavelet_decomposition(dsp_in, window_size, ex_coeff_d->values);
00442
00443 tree_copy(ex_coeff_r->values, ex_coeff_d->values, window_size, levels);
00444 tree_copy(ex_coeff_rn->values, ex_coeff_d->values, window_size, levels);
00445
00446
00447
00448 threshold(window_size, config.level * 10.0, levels);
00449
00450 wavelet_reconstruction(ex_coeff_r->values, window_size, dsp_iteration);
00451 wavelet_reconstruction(ex_coeff_rn->values, window_size, dsp_in);
00452
00453 for(i = 0; i < window_size; i++)
00454 dsp_out[i] += dsp_iteration[i];
00455 }
00456 }
00457
00458
00459
00460
00461 int DenoiseEffect::process_realtime(int64_t size, double *input_ptr, double *output_ptr)
00462 {
00463 load_configuration();
00464
00465 if(!initialized)
00466 {
00467 int64_t size_factor = (int)(pow(2, levels));
00468 dsp_in = new double[window_size * size_factor];
00469 dsp_out = new double[window_size * 2];
00470 dsp_iteration = new double[window_size * 2];
00471
00472
00473 ex_coeff_d = new Tree(window_size, levels);
00474 ex_coeff_r = new Tree(window_size, levels);
00475 ex_coeff_rn = new Tree(window_size, levels);
00476 wave_coeff_d = new WaveletCoeffs(alpha, beta);
00477 wave_coeff_r = new WaveletCoeffs(alpha, beta);
00478 decomp_filter = new WaveletFilters(wave_coeff_d, DECOMP);
00479 recon_filter = new WaveletFilters(wave_coeff_r, RECON);
00480 in_scale = 65535 / sqrt(window_size) / iterations;
00481 out_scale = output_level / 65535 * sqrt(window_size);
00482 initialized = 1;
00483 }
00484
00485
00486 if(input_size + size > input_allocation)
00487 {
00488 double *new_input = new double[input_size + size];
00489 if(input_buffer)
00490 {
00491 memcpy(new_input, input_buffer, sizeof(double) * input_size);
00492 delete [] input_buffer;
00493 }
00494 input_buffer = new_input;
00495 input_allocation = input_size + size;
00496 }
00497 memcpy(input_buffer + input_size,
00498 input_ptr,
00499 size * sizeof(double));
00500 input_size += size;
00501
00502
00503
00504 while(input_size >= window_size)
00505 {
00506
00507 for(int i = 0; i < window_size; i++)
00508 {
00509 dsp_in[i] = input_buffer[i] * in_scale;
00510 }
00511 bzero(dsp_out, sizeof(double) * window_size);
00512
00513
00514
00515
00516
00517
00518
00519 if(!first_window)
00520 process_window();
00521 first_window = 0;
00522
00523
00524
00525
00526
00527
00528
00529 int64_t new_allocation = output_size + window_size;
00530 if(new_allocation > output_allocation)
00531 {
00532 double *new_output = new double[new_allocation];
00533
00534 if(output_buffer)
00535 {
00536 memcpy(new_output, output_buffer, sizeof(double) * output_size);
00537
00538 delete [] output_buffer;
00539
00540 }
00541 output_buffer = new_output;
00542 output_allocation = new_allocation;
00543 }
00544
00545 if(output_size >= WINDOW_BORDER)
00546 {
00547 for(int i = 0, j = output_size - WINDOW_BORDER;
00548 i < WINDOW_BORDER;
00549 i++, j++)
00550 {
00551 double src_level = (double)i / WINDOW_BORDER;
00552 double dst_level = (double)(WINDOW_BORDER - i) / WINDOW_BORDER;
00553 output_buffer[j] = output_buffer[j] * dst_level + out_scale * dsp_out[i] * src_level;
00554 }
00555
00556 for(int i = 0; i < window_size - WINDOW_BORDER; i++)
00557 output_buffer[output_size + i] = dsp_out[WINDOW_BORDER + i] * out_scale;
00558 output_size += window_size - WINDOW_BORDER;
00559 }
00560 else
00561 {
00562
00563 memcpy(output_buffer + output_size,
00564 dsp_out,
00565 sizeof(double) * window_size);
00566 output_size += window_size;
00567 }
00568
00569
00570
00571 for(int i = window_size - WINDOW_BORDER, j = 0;
00572 i < input_size;
00573 i++, j++)
00574 input_buffer[j] = input_buffer[i];
00575 input_size -= window_size - WINDOW_BORDER;
00576 }
00577
00578
00579
00580 if(output_size - WINDOW_BORDER >= size)
00581 {
00582 memcpy(output_ptr, output_buffer, sizeof(double) * size);
00583 for(int i = size, j = 0; i < output_size; i++, j++)
00584 output_buffer[j] = output_buffer[i];
00585 output_size -= size;
00586 }
00587 else
00588 {
00589
00590 bzero(output_ptr, sizeof(double) * size);
00591 }
00592
00593 return 0;
00594 }
00595
00596
00597
00598
00599
00600
00601
00602 Tree::Tree(int input_length, int levels)
00603 {
00604 this->input_length = input_length;
00605 this->levels = levels;
00606 int i, j;
00607
00608
00609 values = new double*[2 * levels];
00610 j = input_length;
00611 for (i = 0; i < levels; i++)
00612 {
00613 j /= 2;
00614 if (j == 0)
00615 {
00616 levels = i;
00617 continue;
00618 }
00619 values[2 * i] = new double[j + 5];
00620 values[2 * i + 1] = new double[j + 5];
00621 }
00622 }
00623
00624 Tree::~Tree()
00625 {
00626 int i;
00627
00628 for (i = 2 * levels - 1; i >= 0; i--)
00629 delete values[i];
00630
00631 delete values;
00632 }
00633
00634 WaveletCoeffs::WaveletCoeffs(double alpha, double beta)
00635 {
00636 int i;
00637 double tcosa = cos(alpha);
00638 double tcosb = cos(beta);
00639 double tsina = sin(alpha);
00640 double tsinb = sin(beta);
00641
00642
00643 values[0] = ((1.0 + tcosa + tsina) * (1.0 - tcosb - tsinb)
00644 + 2.0 * tsinb * tcosa) / 4.0;
00645 values[1] = ((1.0 - tcosa + tsina) * (1.0 + tcosb - tsinb)
00646 - 2.0 * tsinb * tcosa) / 4.0;
00647
00648 tcosa = cos(alpha - beta);
00649 tsina = sin(alpha - beta);
00650
00651
00652
00653 values[2] = (1.0 + tcosa + tsina) / 2.0;
00654 values[3] = (1.0 + tcosa - tsina) / 2.0;
00655 values[4] = 1 - values[0] - values[2];
00656 values[5] = 1 - values[1] - values[3];
00657
00658
00659 for (i = 0; i < 6; i++)
00660 {
00661 if (fabs(values[i]) < 1.0e-15) values[i] = 0.0;
00662 }
00663 }
00664
00665 WaveletCoeffs::~WaveletCoeffs()
00666 {
00667 }
00668
00669
00670 WaveletFilters::WaveletFilters(WaveletCoeffs *wave_coeffs, wavetype transform)
00671 {
00672 int i, j, k;
00673
00674
00675 i = 0;
00676 while(wave_coeffs->values[i] == 0.0) i++;
00677
00678
00679 j = 5;
00680 while(wave_coeffs->values[j] == 0.0) j--;
00681
00682
00683
00684
00685 length = j - i + 1;
00686 for(k = 0; k < length; k++)
00687 {
00688 if (transform == DECOMP)
00689 {
00690 h[k] = wave_coeffs->values[j--] / 2.0;
00691 g[k] = (double) (((i++ & 0x01) * 2) - 1) * wave_coeffs->values[i] / 2.0;
00692 }
00693 else
00694 {
00695 h[k] = wave_coeffs->values[i++];
00696 g[k] = (double) (((j-- & 0x01) * 2) - 1) * wave_coeffs->values[j];
00697 }
00698 }
00699
00700
00701 while (k < 6)
00702 {
00703 h[k] = 0.0;
00704 g[k++] = 0.0;
00705 }
00706 }
00707
00708 WaveletFilters::~WaveletFilters()
00709 {
00710 }
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 DenoiseConfig::DenoiseConfig()
00721 {
00722 level = 1.0;
00723 }
00724
00725 void DenoiseConfig::copy_from(DenoiseConfig &that)
00726 {
00727 level = that.level;
00728 }
00729
00730 int DenoiseConfig::equivalent(DenoiseConfig &that)
00731 {
00732 return EQUIV(level, that.level);
00733 }
00734
00735 void DenoiseConfig::interpolate(DenoiseConfig &prev,
00736 DenoiseConfig &next,
00737 int64_t prev_frame,
00738 int64_t next_frame,
00739 int64_t current_frame)
00740 {
00741 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
00742 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
00743 this->level = prev.level * prev_scale + next.level * next_scale;
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 PLUGIN_THREAD_OBJECT(DenoiseEffect, DenoiseThread, DenoiseWindow)
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 DenoiseWindow::DenoiseWindow(DenoiseEffect *plugin, int x, int y)
00767 : BC_Window(plugin->gui_string,
00768 x,
00769 y,
00770 150,
00771 50,
00772 150,
00773 50,
00774 0,
00775 0,
00776 1)
00777 {
00778 this->plugin = plugin;
00779 }
00780
00781 void DenoiseWindow::create_objects()
00782 {
00783 int x = 10, y = 10;
00784
00785 add_subwindow(new BC_Title(x, y, _("Level:")));
00786 x += 70;
00787 add_subwindow(scale = new DenoiseLevel(plugin, x, y));
00788 show_window();
00789 flush();
00790 }
00791
00792 int DenoiseWindow::close_event()
00793 {
00794
00795 set_done(1);
00796 return 1;
00797 }
00798
00799 void DenoiseWindow::update()
00800 {
00801 scale->update(plugin->config.level);
00802 }
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815 DenoiseLevel::DenoiseLevel(DenoiseEffect *plugin, int x, int y)
00816 : BC_FPot(x, y, (float)plugin->config.level, 0, 1.0)
00817 {
00818 this->plugin = plugin;
00819 set_precision(0.01);
00820 }
00821
00822 int DenoiseLevel::handle_event()
00823 {
00824 plugin->config.level = get_value();
00825 plugin->send_configure_change();
00826 return 1;
00827 }
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843