Hello Einar,

Sorry about taking so long to integrate your feedback. The amended code is v0.2
ob GitHub <https://github.com/Pluies/C41/tree/v0.2>.

I addressed all the issues you mentioned, apart from three which I'm unsure
about:

> As I understand there is no need for c41.h and c41window.h
Those headers files are needed because the two files are coupled —
obviously the plugin needs to access its window, but the window and its
thread also need to know about C41main. I don't see how to delete those
headers without moving all the code to c41.C, which would make it a way
longer and harder to read file. My knowledge of linking in C and C++ is
quite rusty, so if you know of a better way to achieve this, let me know
and I'll implement it.

> *Allocate everything once if needed and delete in destructor*
The matrices I get there have to be of the frame size, and as far as I know
the frame size isn't known at instantiation time, it depends on the frame
passed to process_buffer.

> *Use BC_Title instead of C41TextBox, to reflect the fact that min_r,
min_g... are unchangeable*
On purely subjective grounds, I think it makes more sense visually to have
an unmodifiable TextBox instead of a changing "title". That way, the user
can see immediately that these variables must be computed somehow, whereas
having them as a title could lead to thing they're static.

Looking forward to hearing from your feedback.

Regards,
Florent Delannoy

On 31 December 2011 11:33, Einar Rünkaru <eina...@smail.ee> wrote:

> Hi.
>
> As I understand there is no need for c41.h and c41window.h. I looked at
> c41.c
> I numbered the lines and left only parts I commented.
> <snip>
>     53
>     54                  int active, compute_magic;
>
>     55                  float min_r, min_g, min_b, magic4, magic5, magic6;
> Move them out from Config as these are always computed values. Config must
> cotain only
> user changeable parameters
>
>     56                  float fix_min_r, fix_min_g, fix_min_b, fix_magic4,
> fix_magic5, fix_magic6;
> Declare every variable on a separate line
>     57  };
> One tab more than needed. Class declaration template
> class MyClass {
> public:
> <tab>MyClass();
>
> private:
> <tab>int a_var;
> };
>
>    169  int C41Config::equivalent(C41Config &src)
>    170  {
>    171          return false;
>    172  }
> Why empty function? With the help of this decision is made wether the gui
> need to be updated
>    173  void C41Config::interpolate(C41Config &prev,
>    174                  C41Config &next,
>    175                  long prev_frame,
>    176                  long next_frame,
>    177                  long current_frame)
>    178  {
>    179          active = prev.active;
>
>    193          fix_magic5 = prev.fix_magic5;
>    194          fix_magic6 = prev.fix_magic6;
>    195
>    196  }
> No need for empty line before closing brace
> I think it is reasonable to interpolate the values - user may want
> changing parameters
>    197
>    198  // C41Enable
>    199          C41Enable::C41Enable(C41Effect *plugin, int *output, int
> x, int y, char *text)
>    200  : BC_CheckBox(x, y, *output, text)
> Indentation of a constructor:
> MyClass::MyClass()
> <space>:<space>ParentConstructor()
>    201  {
>    202          this->plugin = plugin;
>    203          this->output = output;
>    204  }
> One empty line between methods
>    205  int C41Enable::handle_event()
>    206  {
>
>    246  void C41Window::create_objects()
>    247  {
>
>    260
>    261          add_subwindow(new BC_Title(x, y, _("Min R:")));
>    262          add_subwindow(min_r = new C41TextBox(plugin,
> &plugin->config.min_r, x+60, y));
>    263          y += 30;
> Use BC_Title instead of C41TextBox, to reflect the fact that min_r,
> min_g... are unchangeable
>
>    345
>    346          NEW_PICON_MACRO(C41Effect)
>    347          SHOW_GUI_MACRO(C41Effect, C41Thread)
>    348          RAISE_WINDOW_MACRO(C41Effect)
>    349          SET_STRING_MACRO(C41Effect)
> No tab here
>    350  LOAD_CONFIGURATION_MACRO(C41Effect, C41Config)
>    351
>
>    362
>    363  void C41Effect::update_gui()
>    364  {
>    365          // We don't use update_gui, but rather render_gui.
>    366          // However, the method is still needed to instantiate the
> plugin
>    350  LOAD_CONFIGURATION_MACRO(C41Effect, C41Config)
>    351
>
>    362
>    363  void C41Effect::update_gui()
>    364  {
>    365          // We don't use update_gui, but rather render_gui.
>    366          // However, the method is still needed to instantiate the
> plugin
> Here should be:
> if(thread && load_configuration)
> {
>         thread->window->lock_window("C41Effect::update_gui");
>         thread->window->update();
>         thread->window->unlock_window();
> }
>    367
>    368  }
> - update_gui will be macro in the future
>
>   370
>    371  void C41Effect::render_gui(void* data)
>    372  {
>    373          if(thread)
>    374          {
>    375                  if(load_configuration()){
>    376                          thread->window->lock_window();
>    377
>
>    386
>    387                          // Updating the GUI itself
>    388
> thread->window->active->update(config.active);
>    389
> thread->window->compute_magic->update(config.compute_magic);
>    390
>    391
> thread->window->min_r->update(config.min_r);
>    392
> thread->window->min_g->update(config.min_g);
>    393
> thread->window->min_b->update(config.min_b);
>    394
> thread->window->magic4->update(config.magic4);
>    395
> thread->window->magic5->update(config.magic5);
>    396
> thread->window->magic6->update(config.magic6);
>    397
>    398
> thread->window->fix_min_r->update(config.fix_min_r);
>    399
> thread->window->fix_min_g->update(config.fix_min_g);
>    400
> thread->window->fix_min_b->update(config.fix_min_b);
>    401
> thread->window->fix_magic4->update(config.fix_magic4);
>    402
> thread->window->fix_magic5->update(config.fix_magic5);
>    403
> thread->window->fix_magic6->update(config.fix_magic6);
> Create C41Window::update() and move all updates there
>
>    404
>    405                          // DEBUG
>    406                          // printf("UPDATING GUI with RENDER and
> values %f %f %f\n", config.min_r,
> Remove all debug messages
>    407                          free(data);
> Do not use dynamic allocations unless explictly needed
>    408
>    409                          thread->window->unlock_window();
>    410                  }
>    411          }
>    412
>    413  }
>    414
>    415  int C41Effect::load_defaults()
>    416  {
>
>    424          config.min_r = defaults->get("MIN_R", config.min_r);
>    425          config.min_g = defaults->get("MIN_G", config.min_g);
>    426          config.min_b = defaults->get("MIN_B", config.min_b);
>    427          config.magic4 = defaults->get("MAGIC4", config.magic4);
>    428          config.magic5 = defaults->get("MAGIC5", config.magic5);
>    429          config.magic6 = defaults->get("MAGIC6", config.magic6);
> As min_r...magic6 are always computed and never changed by user there is
> no point to save/load them
>    430
>
>    513
>    514  // Computes the difference (in nanoseconds) between two timespec
>    515  double C41Effect::difftime_nano(timespec start, timespec end)
>    516  {
>
>    526  }
> Do not leave debug functions into release
>
>    528  /* Faster pow() approximation; borrowed from
> http://www.dctsystems.co.uk/Software/power.html
>    529   * Tests on real-world data showed a max error of 4% and avg.
> error or .1 to .5%,
>    530   * while accelerating rendering by a factor of 4.
>    531   */
>    532  float C41Effect::log2(float i)
>    533  {
>    534          return(log(i)/log(2));
>    535  }
> Remove unused functions
>    537  float C41Effect::myLog2(float i)
>    538  {
>    539          float x, y, LogBodge=0.346607f;
>    540          x=*(int *)&i;
>    541          x*= 1.0/(1<<23); //1/pow(2,23);
>    542          x=x-127;
>    543
>    544          y=x-floorf(x);
>    545          y=(y-y*y)*LogBodge;
>    546          return x+y;
> Use spaces around operators, example: c = a + (b + c)
>    547  }
>
>    562  float C41Effect::myPow(float a, float b)
>    563  {
>    564          return myPow2(b*myLog2(a));
>    565  }
>    566
>    567
>    568
> No more than 2 empty lines
>    569  int C41Effect::process_buffer(VFrame *frame,
>    570                  int64_t start_position,
>    571                  double frame_rate)
>    572  {
>    573          load_configuration();
>    574
>    575          read_frame(frame,
>    576                          0,
>    577                          start_position,
>    578                          frame_rate,
>    579                          get_use_opengl());
> Drop get_use_opengl, if you do not support OpenGL
>    580
>    581          int frame_w = frame->get_w();
>    582          int frame_h = frame->get_h();
>    583
>    584          switch(frame->get_color_model())
>    585          {
>    586                  case BC_RGB888:
>    587                  case BC_YUV888:
>    588                  case BC_RGBA_FLOAT:
>    589                  case BC_RGBA8888:
>    590                  case BC_YUVA8888:
>    591                  case BC_RGB161616:
>    592                  case BC_YUV161616:
>    593                  case BC_RGBA16161616:
>    594                  case BC_YUVA16161616:
>    595                          return 0; // Unsupported
>    596                          break;
> No need for break
>    597                  case BC_RGB_FLOAT:
>    598                          break;
>    599          }
>    600
>    601          float magic1, magic2, magic3, magic4, magic5, magic6;
>    602
>    603          // Profiling
>    604          timespec start,middle,end;
>    605          clock_gettime(CLOCK_REALTIME, &start);
> No profiling in release
>    606
>    607          if(config.compute_magic){
>    608
>    609                  // Box blur!
>    610                  VFrame* tmp_frame = new VFrame(*frame);
>    611                  VFrame* blurry_frame = new VFrame(*frame);
>    612
>    613                  float** rows = (float**)frame->get_rows();
>    614                  float** tmp_rows = (float**)tmp_frame->get_rows();
>    615                  float** blurry_rows =
> (float**)blurry_frame->get_rows();
>    616                  for(int i = 0; i < frame_h; i++)
>    617                          for(int j = 0; j < (3*frame_w); j++)
>    618                                  blurry_rows[i][j] = rows[i][j];
> Allocate everything once if needed and delete in destructor
>    619
>    620                  int boxw = 5, boxh = 5;
>    621                  // 3 passes of Box blur should be good
>    622                  int pass,x,y,y_up,y_down,x_right,x_left;
> Spacing: int pass, x, y, y_up, y_down, x_right, x_left;
>
>    636
> component=(tmp_rows[y_down][x_right]
>    637
> +tmp_rows[y_up][x_left]
>    638
> +tmp_rows[y_up][x_right]
>    639
> +tmp_rows[y_down][x_right])/4;
>    640                                          //if( i%250==1 && j%250==1
> ) printf("values, i=%d j=%d tot
> Debug print
>    641                                          blurry_rows[y][x]=
> component;
>    642                                  }
>    643                          }
>    644                  }
>
>    663                                  if(row[0]<minima_r) minima_r =
> row[0];
> Spacing: if(row[0] < minima_r)
>
>    677
>    678                  // DEBUG
>    679                  //printf("Minima: %f %f %f\n", minima_r, minima_g,
> minima_b);
>    680                  //printf("Maxima: %f %f %f\n", maxima_r, maxima_g,
> maxima_b);
> Remove debug messages, please
>
>    685                  magic5 = log(maxima_g/minima_g) /
> log(maxima_r/minima_r);
>    686                  magic6 = log(maxima_b/minima_b) /
> log(maxima_r/minima_r);
> As below is used 1 / magic{5,6} the division can be reverted
>    687                  // DEBUG
>    688                  // printf("Magic values: %f %f %f\n", magic4,
> magic5, magic
> Debug messages
>    690                  // Update GUI
> Spaces at the end of line
>    691                  float *nf_vals = (float*) malloc(6*sizeof(float));
> Why allocation? Use float nf_vals[6] in class data
> This causes memory leak, when plugin runs and gui is inactive.
>
>    696
>    697          clock_gettime(CLOCK_REALTIME, &middle);
> Profiling subsystem - should be removed
>    725
>    726          clock_gettime(CLOCK_REALTIME, &end);
> Profiling
>    727
>    728          // Profiling
>    729          // printf("Time elapsed: %f (computing magic values), %f
> (processing image), %f total\n",
>    730
> Out commented debug messages
>    731          /* END NEGFIX */
>    732
>    733          return 0;
>    734  }
>    735
>
>    736  int C41Effect::handle_opengl()
>    737  {
>    738  #ifdef HAVE_GL
>    739          /* TODO */
>    740          /* NOT IMPLEMENTED */
>    741          /* TODO */
>    742  #endif
>    743  }
> No need, if opengl is unsupported here
>
>
> Einar
>

Reply via email to