rework histogram_bezier, init wm icon set_icon(gg), update de.po+msg/txt
[goodguy/history.git] / cinelerra-5.1 / plugins / histogram_bezier / bistogram.C
index 1f786f957d287155156f4e26ca15037807846bfc..2ad9c17dfa66e239a467047948e0bf9f1352a08a 100644 (file)
@@ -49,10 +49,8 @@ REGISTER_PLUGIN(HistogramMain)
 HistogramMain::HistogramMain(PluginServer *server)
  : PluginVClient(server)
 {
-
        engine = 0;
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
+       for( int i=0; i<HISTOGRAM_MODES; ++i ) {
                lookup[i] = 0;
                smoothed[i] = 0;
                linear[i] = 0;
@@ -63,19 +61,24 @@ HistogramMain::HistogramMain(PluginServer *server)
        dragging_point = 0;
        input = 0;
        output = 0;
+       slots = 0;
 }
 
 HistogramMain::~HistogramMain()
 {
+       reset();
+}
 
-       for(int i = 0; i < HISTOGRAM_MODES;i++)
-       {
-               delete [] lookup[i];
-               delete [] smoothed[i];
-               delete [] linear[i];
-               delete [] accum[i];
+void HistogramMain::reset()
+{
+       for( int i=0; i<HISTOGRAM_MODES; ++i ) {
+               delete [] lookup[i];    lookup[i] = 0;
+               delete [] smoothed[i];  smoothed[i] = 0;
+               delete [] linear[i];    linear[i] = 0;
+               delete [] accum[i];     accum[i] = 0;
        }
-       delete engine;
+       delete engine;  engine = 0;
+       slots = 0;
 }
 
 const char* HistogramMain::plugin_title() { return N_("Histogram Bezier"); }
@@ -89,12 +92,10 @@ void HistogramMain::render_gui(void *data)
 {
        if(thread)
        {
-               calculate_histogram((VFrame*)data);
-
-               if(config.automatic)
-               {
-                       calculate_automatic((VFrame*)data);
-               }
+               VFrame *input = (VFrame *)data;
+               calculate_histogram(input);
+               if( config.automatic )
+                       calculate_automatic(input);
 
                HistogramWindow *window = (HistogramWindow *)thread->window;
                window->lock_window("HistogramMain::render_gui");
@@ -133,8 +134,7 @@ void HistogramMain::save_data(KeyFrame *keyframe)
        char string[BCTEXTLEN];
 
 
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
+       for( int i=0; i<HISTOGRAM_MODES; ++i ) {
                sprintf(string, "OUTPUT_MIN_%d", i);
                output.tag.set_property(string, config.output_min[i]);
                sprintf(string, "OUTPUT_MAX_%d", i);
@@ -155,16 +155,14 @@ void HistogramMain::save_data(KeyFrame *keyframe)
 
 
 
-       for(int j = 0; j < HISTOGRAM_MODES; j++)
-       {
+       for( int j=0; j<HISTOGRAM_MODES; ++j ) {
                output.tag.set_title("POINTS");
                output.append_tag();
                output.append_newline();
 
 
                HistogramPoint *current = config.points[j].first;
-               while(current)
-               {
+               while( current ) {
                        output.tag.set_title("POINT");
                        output.tag.set_property("X", current->x);
                        output.tag.set_property("Y", current->y);
@@ -202,63 +200,41 @@ void HistogramMain::read_data(KeyFrame *keyframe)
        int current_input_mode = 0;
 
 
-       while(!result)
-       {
-               result = input.read_tag();
-
-               if(!result)
-               {
-                       if(input.tag.title_is("HISTOGRAM"))
-                       {
-                               char string[BCTEXTLEN];
-                               for(int i = 0; i < HISTOGRAM_MODES; i++)
-                               {
-                                       sprintf(string, "OUTPUT_MIN_%d", i);
-                                       config.output_min[i] = input.tag.get_property(string, config.output_min[i]);
-                                       sprintf(string, "OUTPUT_MAX_%d", i);
-                                       config.output_max[i] = input.tag.get_property(string, config.output_max[i]);
+       while( !(result = input.read_tag()) ) {
+               if( input.tag.title_is("HISTOGRAM") ) {
+                       char string[BCTEXTLEN];
+                       for( int i=0; i<HISTOGRAM_MODES; ++i ) {
+                               sprintf(string, "OUTPUT_MIN_%d", i);
+                               config.output_min[i] = input.tag.get_property(string, config.output_min[i]);
+                               sprintf(string, "OUTPUT_MAX_%d", i);
+                               config.output_max[i] = input.tag.get_property(string, config.output_max[i]);
 //printf("HistogramMain::read_data %d %f %d\n", config.input_min[i], config.input_mid[i], config.input_max[i]);
-                               }
-                               config.automatic = input.tag.get_property("AUTOMATIC", config.automatic);
-                               config.threshold = input.tag.get_property("THRESHOLD", config.threshold);
-                               config.split = input.tag.get_property("SPLIT", config.split);
-                               config.smoothMode = input.tag.get_property("INTERPOLATION", config.smoothMode);
                        }
-                       else
-                       if(input.tag.title_is("POINTS"))
-                       {
-                               if(current_input_mode < HISTOGRAM_MODES)
-                               {
-                                       HistogramPoints *points = &config.points[current_input_mode];
-                                       while(points->last)
-                                               delete points->last;
-                                       while(!result)
-                                       {
-                                               result = input.read_tag();
-                                               if(!result)
-                                               {
-                                                       if(input.tag.title_is("/POINTS"))
-                                                       {
-                                                               break;
-                                                       }
-                                                       else
-                                                       if(input.tag.title_is("POINT"))
-                                                       {
-                                                               points->insert(
-                                                                       input.tag.get_property("X", 0.0),
-                                                                       input.tag.get_property("Y", 0.0));
-                                                               points->last->gradient =
-                                                                       input.tag.get_property("GRADIENT", 1.0);
-                                                               points->last->xoffset_left =
-                                                                       input.tag.get_property("XOFFSET_LEFT", -0.02);
-                                                               points->last->xoffset_right =
-                                                                       input.tag.get_property("XOFFSET_RIGHT", 0.02);
-                                                       }
-                                               }
+                       config.automatic = input.tag.get_property("AUTOMATIC", config.automatic);
+                       config.threshold = input.tag.get_property("THRESHOLD", config.threshold);
+                       config.split = input.tag.get_property("SPLIT", config.split);
+                       config.smoothMode = input.tag.get_property("INTERPOLATION", config.smoothMode);
+               }
+               else if( input.tag.title_is("POINTS") ) {
+                       if( current_input_mode < HISTOGRAM_MODES ) {
+                               HistogramPoints *points = &config.points[current_input_mode];
+                               while( points->last )
+                                       delete points->last;
+                               while( !(result = input.read_tag()) ) {
+                                       if( input.tag.title_is("/POINTS") ) break;
+                                       if(input.tag.title_is("POINT") ) {
+                                               points->insert(
+                                                       input.tag.get_property("X", 0.0),
+                                                       input.tag.get_property("Y", 0.0));
+                                               points->last->gradient =
+                                                       input.tag.get_property("GRADIENT", 1.0);
+                                               points->last->xoffset_left =
+                                                       input.tag.get_property("XOFFSET_LEFT", -0.02);
+                                               points->last->xoffset_right =
+                                                       input.tag.get_property("XOFFSET_RIGHT", 0.02);
                                        }
-
                                }
-                               current_input_mode++;
+                               ++current_input_mode;
                        }
                }
        }
@@ -297,8 +273,8 @@ float HistogramMain::calculate_linear(float input,
                HistogramPoints *points = &config.points[subscript];
                HistogramPoint *current = points->first;
                int done = 0;
-               while(current && !done) {
-                       if(current->x > input) {
+               while( current && !done ) {
+                       if( current->x > input ) {
                                x2 = current->x;
                                y2 = current->y;
                                grad2 = current->gradient;
@@ -311,8 +287,8 @@ float HistogramMain::calculate_linear(float input,
 
                current = points->last;
                done = 0;
-               while(current && !done) {
-                       if(current->x <= input) {
+               while( current && !done ) {
+                       if( current->x <= input ) {
                                x1 = current->x;
                                y1 = current->y;
                                grad1 = current->gradient;
@@ -323,24 +299,18 @@ float HistogramMain::calculate_linear(float input,
                                current = PREVIOUS;
                }
 
-
-
-
-               if(!EQUIV(x2 - x1, 0))
-               {
-                 if (config.smoothMode == HISTOGRAM_LINEAR)
+               if( !EQUIV(x2 - x1, 0) ) {
+                 if( config.smoothMode == HISTOGRAM_LINEAR )
                        output = (input - x1) * (y2 - y1) / (x2 - x1) + y1;
-                 else if (config.smoothMode == HISTOGRAM_POLYNOMINAL)
-                 {
+                 else if( config.smoothMode == HISTOGRAM_POLYNOMINAL ) {
                        /* Construct third grade polynom between every two points */
                        float dx = x2 - x1;
                        float dy = y2 - y1;
                        float delx = input - x1;
                        output = (grad2 * dx + grad1 * dx - 2*dy) / (dx * dx * dx) * delx * delx * delx +
-                        (3*dy - 2* grad1*dx - grad2*dx) / (dx * dx) * delx * delx + grad1*delx + y1;
+                               (3*dy - 2* grad1*dx - grad2*dx) / (dx * dx) * delx * delx + grad1*delx + y1;
                  }
-                 else if (config.smoothMode == HISTOGRAM_BEZIER)
-                 {
+                 else if( config.smoothMode == HISTOGRAM_BEZIER ) {
                        /* Using standart DeCasteljau algorithm */
                        float y1right = y1 + grad1 * x1right;
                        float y2left = y2 + grad2 * x2left;
@@ -361,7 +331,7 @@ float HistogramMain::calculate_linear(float input,
        }
 
 // Apply value curve
-       if(use_value) {
+       if( use_value ) {
                output = calculate_linear(output, HISTOGRAM_VALUE, 0);
        }
 
@@ -376,12 +346,14 @@ float HistogramMain::calculate_linear(float input,
 
 float HistogramMain::calculate_smooth(float input, int subscript)
 {
-       float x_f = (input - HIST_MIN_INPUT) * HISTOGRAM_SLOTS / FLOAT_RANGE;
+       int bins = slots * (HISTOGRAM_MAX-HISTOGRAM_MIN)/100;
+       int bins1 = bins-1;
+       float x_f = (input - HIST_MIN_INPUT) * bins / FLOAT_RANGE;
        int x_i1 = (int)x_f;
        int x_i2 = x_i1 + 1;
-       CLAMP(x_i1, 0, HISTOGRAM_SLOTS-1);
-       CLAMP(x_i2, 0, HISTOGRAM_SLOTS-1);
-       CLAMP(x_f, 0, HISTOGRAM_SLOTS-1);
+       CLAMP(x_i1, 0, bins1);
+       CLAMP(x_i2, 0, bins1);
+       CLAMP(x_f, 0, bins1);
 
        float smooth1 = smoothed[subscript][x_i1];
        float smooth2 = smoothed[subscript][x_i2];
@@ -393,39 +365,47 @@ float HistogramMain::calculate_smooth(float input, int subscript)
 
 void HistogramMain::calculate_histogram(VFrame *data)
 {
+       int color_model = data->get_color_model();
+       int pix_sz = BC_CModels::calculate_pixelsize(color_model);
+       int comp_sz = pix_sz / BC_CModels::components(color_model);
+       int needed_slots = comp_sz > 1 ? 0x10000 : 0x100;
+       if( slots != needed_slots ) {
+               reset();
+               slots = needed_slots;
+       }
+       int bins = slots * (HISTOGRAM_MAX-HISTOGRAM_MIN)/100;
+       if( !accum[0] ) {
+               for( int i=0; i<HISTOGRAM_MODES; ++i )
+                       accum[i] = new int[bins];
+       }
 
-       if(!engine) engine = new HistogramEngine(this,
-               get_project_smp() + 1,
-               get_project_smp() + 1);
-
-       if(!accum[0])
-       {
-               for(int i = 0; i < HISTOGRAM_MODES; i++)
-                       accum[i] = new int[HISTOGRAM_SLOTS];
+       if( !engine ) {
+               int cpus = data->get_w() * data->get_h() * pix_sz / 0x80000 + 2;
+               int smps = get_project_smp();
+               if( cpus > smps ) cpus = smps;
+               engine = new HistogramEngine(this, cpus, cpus);
        }
        engine->process_packages(HistogramEngine::HISTOGRAM, data);
 
-       for(int i = 0; i < engine->get_total_clients(); i++) {
+       for( int i=0; i<engine->get_total_clients(); ++i ) {
                HistogramUnit *unit = (HistogramUnit*)engine->get_client(i);
-               if(i == 0) {
-                       for(int j = 0; j < HISTOGRAM_MODES; j++)
-                               memcpy(accum[j], unit->accum[j], sizeof(int) * HISTOGRAM_SLOTS);
+               if( i == 0 ) {
+                       for( int j=0; j<HISTOGRAM_MODES; ++j )
+                               memcpy(accum[j], unit->accum[j], sizeof(int)*bins);
                }
                else {
-                       for(int j = 0; j < HISTOGRAM_MODES; j++) {
-                               int *out = accum[j];
-                               int *in = unit->accum[j];
-                               for(int k = 0; k < HISTOGRAM_SLOTS; k++)
-                                       out[k] += in[k];
+                       for( int j=0; j<HISTOGRAM_MODES; ++j ) {
+                               int *out = accum[j], *in = unit->accum[j];
+                               for( int k=0; k<bins; ++k ) out[k] += in[k];
                        }
                }
        }
 
 // Remove top and bottom from calculations.  Doesn't work in high
 // precision colormodels.
-       for(int i = 0; i < HISTOGRAM_MODES; i++) {
+       for( int i=0; i<HISTOGRAM_MODES; ++i ) {
                accum[i][0] = 0;
-               accum[i][HISTOGRAM_SLOTS - 1] = 0;
+               accum[i][bins-1] = 0;
        }
 }
 
@@ -434,9 +414,10 @@ void HistogramMain::calculate_automatic(VFrame *data)
 {
        calculate_histogram(data);
        config.reset_points();
+       int bins = slots * (HISTOGRAM_MAX-HISTOGRAM_MIN)/100;
 
 // Do each channel
-       for(int i = 0; i < 3; i++) {
+       for( int i=0; i<3; ++i ) {
                int *accum = this->accum[i];
                int pixels = data->get_w() * data->get_h();
                float white_fraction = 1.0 - (1.0 - config.threshold) / 2;
@@ -444,22 +425,21 @@ void HistogramMain::calculate_automatic(VFrame *data)
                int total = 0;
                float max_level = 1.0;
                float min_level = 0.0;
-
 // Get histogram slot above threshold of pixels
-               for(int j = 0; j < HISTOGRAM_SLOTS; j++) {
+               for( int j=0; j<bins; ++j ) {
                        total += accum[j];
-                       if(total >= threshold) {
-                               max_level = (float)j / HISTOGRAM_SLOTS * FLOAT_RANGE + HIST_MIN_INPUT;
+                       if( total >= threshold ) {
+                               max_level = (float)j/bins * FLOAT_RANGE + HIST_MIN_INPUT;
                                break;
                        }
                }
 
 // Get slot below 99% of pixels
                total = 0;
-               for(int j = HISTOGRAM_SLOTS - 1; j >= 0; j--) {
+               for( int j=bins; --j>=0; ) {
                        total += accum[j];
-                       if(total >= threshold) {
-                               min_level = (float)j / HISTOGRAM_SLOTS * FLOAT_RANGE + HIST_MIN_INPUT;
+                       if( total >= threshold ) {
+                               min_level = (float)j/bins * FLOAT_RANGE + HIST_MIN_INPUT;
                                break;
                        }
                }
@@ -470,21 +450,24 @@ void HistogramMain::calculate_automatic(VFrame *data)
 
 int HistogramMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
 {
-SET_TRACE
-       int need_reconfigure = load_configuration();
-SET_TRACE
-
-       if(!engine) engine = new HistogramEngine(this,
-               get_project_smp() + 1,
-               get_project_smp() + 1);
        this->input = input_ptr;
        this->output = output_ptr;
 
-       send_render_gui(input_ptr);
+       int need_reconfigure = load_configuration();
+       int color_model = input->get_color_model();
+       int pix_sz = BC_CModels::calculate_pixelsize(color_model);
+       int comp_sz = pix_sz / BC_CModels::components(color_model);
+       int needed_slots = comp_sz > 1 ? 0x10000 : 0x100;
+       if( slots != needed_slots ) {
+               reset();
+               slots = needed_slots;
+               need_reconfigure = 1;
+       }
+
+       send_render_gui(input);
 
-       if(input_ptr->get_rows()[0] != output_ptr->get_rows()[0])
-       {
-               output_ptr->copy_from(input_ptr);
+       if( input->get_rows()[0] != output_ptr->get_rows()[0] ) {
+               output_ptr->copy_from(input);
        }
 
 SET_TRACE
@@ -496,17 +479,23 @@ SET_TRACE
        if( need_reconfigure ) {
 SET_TRACE
 // Calculate new curves
-               if(config.automatic) {
+               if( config.automatic ) {
                        calculate_automatic(input);
                }
 SET_TRACE
 
 // Generate transfer tables for integer colormodels.
-               for(int i = 0; i < 3; i++)
+               for( int i=0; i<3; ++i )
                        tabulate_curve(i, 1);
 SET_TRACE
        }
 
+       if( !engine ) {
+               int cpus = input->get_w() * input->get_h() * pix_sz / 0x80000 + 2;
+               int smps = get_project_smp();
+               if( cpus > smps ) cpus = smps;
+               engine = new HistogramEngine(this, cpus, cpus);
+       }
 // Apply histogram
        engine->process_packages(HistogramEngine::APPLY, input);
 
@@ -516,48 +505,36 @@ SET_TRACE
 
 void HistogramMain::tabulate_curve(int subscript, int use_value)
 {
-       int i;
+       int bins = slots * (HISTOGRAM_MAX-HISTOGRAM_MIN)/100;
        if(!lookup[subscript])
-               lookup[subscript] = new int[HISTOGRAM_SLOTS];
+               lookup[subscript] = new int[bins];
        if(!smoothed[subscript])
-               smoothed[subscript] = new float[HISTOGRAM_SLOTS];
+               smoothed[subscript] = new float[bins];
        if(!linear[subscript])
-               linear[subscript] = new float[HISTOGRAM_SLOTS];
+               linear[subscript] = new float[bins];
 
        float *current_smooth = smoothed[subscript];
        float *current_linear = linear[subscript];
 
 // Make linear curve
-       for(i = 0; i < HISTOGRAM_SLOTS; i++) {
-               float input = (float)i / HISTOGRAM_SLOTS * FLOAT_RANGE + HIST_MIN_INPUT;
+       for( int i=0; i<bins; ++i ) {
+               float input = (float)i/bins * FLOAT_RANGE + HIST_MIN_INPUT;
                current_linear[i] = calculate_linear(input, subscript, use_value);
        }
 // Make smooth curve
        //float prev = 0.0;
-       for(i = 0; i < HISTOGRAM_SLOTS; i++)
-       {
+       for( int i=0; i<bins; ++i ) {
 //             current_smooth[i] = current_linear[i] * 0.001 +
 //                     prev * 0.999;
                current_smooth[i] = current_linear[i];
 //             prev = current_smooth[i];
        }
 // Generate lookup tables for integer colormodels
-       if(input)
-       {
-               switch(input->get_color_model())
-               {
-                       case BC_RGB888:
-                       case BC_RGBA8888:
-                               for(i = 0; i < 0x100; i++)
-                                       lookup[subscript][i] =
-                                               (int)(calculate_smooth((float)i / 0xff, subscript) * 0xff);
-                               break;
-// All other integer colormodels are converted to 16 bit RGB
-                       default:
-                               for(i = 0; i < 0x10000; i++)
-                                       lookup[subscript][i] =
-                                               (int)(calculate_smooth((float)i / 0xffff, subscript) * 0xffff);
-                               break;
+       if( input ) {
+               int slots1 = slots-1;
+               for( int i=0; i<slots; ++i ) {
+                       lookup[subscript][i] =
+                               (int)(calculate_smooth((float)i/slots1, subscript) * slots1);
                }
        }
 }
@@ -573,47 +550,38 @@ HistogramUnit::HistogramUnit(HistogramEngine *server,
 {
        this->plugin = plugin;
        this->server = server;
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-               accum[i] = new int[HISTOGRAM_SLOTS];
+       int bins = plugin->slots * (HISTOGRAM_MAX-HISTOGRAM_MIN)/100;
+       for( int i=0; i<HISTOGRAM_MODES; ++i )
+               accum[i] = new int[bins];
 }
 
 HistogramUnit::~HistogramUnit()
 {
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
+       for( int i=0; i<HISTOGRAM_MODES; ++i )
                delete [] accum[i];
 }
 
 void HistogramUnit::process_package(LoadPackage *package)
 {
        HistogramPackage *pkg = (HistogramPackage*)package;
-
-       if(server->operation == HistogramEngine::HISTOGRAM)
-       {
+       int bins = plugin->slots * (HISTOGRAM_MAX-HISTOGRAM_MIN)/100;
+       int bins1 = bins-1;
+       int slots1 = -HISTOGRAM_MIN * (plugin->slots-1) / 100;
+       if( server->operation == HistogramEngine::HISTOGRAM ) {
 
 #define HISTOGRAM_HEAD(type) \
 { \
-       for(int i = pkg->start; i < pkg->end; i++) \
-       { \
+       for( int i=pkg->start; i<pkg->end; ++i ) { \
                type *row = (type*)data->get_rows()[i]; \
-               for(int j = 0; j < w; j++) \
-               {
+               for( int j=0; j<w; ++j ) {
 
 #define HISTOGRAM_TAIL(components) \
-/*                     v = (r * 76 + g * 150 + b * 29) >> 8; */ \
-                       v = MAX(r, g); \
-                       v = MAX(v, b); \
-                       r += -HISTOGRAM_MIN * 0xffff / 100; \
-                       g += -HISTOGRAM_MIN * 0xffff / 100; \
-                       b += -HISTOGRAM_MIN * 0xffff / 100; \
-                       v += -HISTOGRAM_MIN * 0xffff / 100; \
-                       CLAMP(r, 0, HISTOGRAM_SLOTS-1); \
-                       CLAMP(g, 0, HISTOGRAM_SLOTS-1); \
-                       CLAMP(b, 0, HISTOGRAM_SLOTS-1); \
-                       CLAMP(v, 0, HISTOGRAM_SLOTS-1); \
-                       accum_r[r]++; \
-                       accum_g[g]++; \
-                       accum_b[b]++; \
-                       accum_v[v]++; \
+                       v = MAX(r, g); v = MAX(v, b); v += slots1; \
+                       r += slots1;  g += slots1;  b += slots1; \
+                       CLAMP(r, 0, bins1);  ++accum_r[r]; \
+                       CLAMP(g, 0, bins1);  ++accum_g[g]; \
+                       CLAMP(b, 0, bins1);  ++accum_b[b]; \
+                       CLAMP(v, 0, bins1);  ++accum_v[v]; \
                        row += components; \
                } \
        } \
@@ -628,99 +596,77 @@ void HistogramUnit::process_package(LoadPackage *package)
                int *accum_v = accum[HISTOGRAM_VALUE];
                int r, g, b, y, u, v;
 
-               switch(data->get_color_model())
-               {
-                       case BC_RGB888:
-                               HISTOGRAM_HEAD(unsigned char)
-                               r = (row[0] << 8) | row[0];
-                               g = (row[1] << 8) | row[1];
-                               b = (row[2] << 8) | row[2];
-                               HISTOGRAM_TAIL(3)
-                               break;
-                       case BC_RGB_FLOAT:
-                               HISTOGRAM_HEAD(float)
-                               r = (int)(row[0] * 0xffff);
-                               g = (int)(row[1] * 0xffff);
-                               b = (int)(row[2] * 0xffff);
-                               HISTOGRAM_TAIL(3)
-                               break;
-                       case BC_YUV888:
-                               HISTOGRAM_HEAD(unsigned char)
-                               y = (row[0] << 8) | row[0];
-                               u = (row[1] << 8) | row[1];
-                               v = (row[2] << 8) | row[2];
-                               YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
-                               HISTOGRAM_TAIL(3)
-                               break;
-                       case BC_RGBA8888:
-                               HISTOGRAM_HEAD(unsigned char)
-                               r = (row[0] << 8) | row[0];
-                               g = (row[1] << 8) | row[1];
-                               b = (row[2] << 8) | row[2];
-                               HISTOGRAM_TAIL(4)
-                               break;
-                       case BC_RGBA_FLOAT:
-                               HISTOGRAM_HEAD(float)
-                               r = (int)(row[0] * 0xffff);
-                               g = (int)(row[1] * 0xffff);
-                               b = (int)(row[2] * 0xffff);
-                               HISTOGRAM_TAIL(4)
-                               break;
-                       case BC_YUVA8888:
-                               HISTOGRAM_HEAD(unsigned char)
-                               y = (row[0] << 8) | row[0];
-                               u = (row[1] << 8) | row[1];
-                               v = (row[2] << 8) | row[2];
-                               YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
-                               HISTOGRAM_TAIL(4)
-                               break;
-                       case BC_RGB161616:
-                               HISTOGRAM_HEAD(uint16_t)
-                               r = row[0];
-                               g = row[1];
-                               b = row[2];
-                               HISTOGRAM_TAIL(3)
-                               break;
-                       case BC_YUV161616:
-                               HISTOGRAM_HEAD(uint16_t)
-                               y = row[0];
-                               u = row[1];
-                               v = row[2];
-                               YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
-                               HISTOGRAM_TAIL(3)
-                               break;
-                       case BC_RGBA16161616:
-                               HISTOGRAM_HEAD(uint16_t)
-                               r = row[0];
-                               g = row[1];
-                               b = row[2];
-                               HISTOGRAM_TAIL(3)
-                               break;
-                       case BC_YUVA16161616:
-                               HISTOGRAM_HEAD(uint16_t)
-                               y = row[0];
-                               u = row[1];
-                               v = row[2];
-                               YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
-                               HISTOGRAM_TAIL(4)
-                               break;
+               switch( data->get_color_model() ) {
+               case BC_RGB888:
+                       HISTOGRAM_HEAD(unsigned char)
+                       r = row[0]; g = row[1]; b = row[2];
+                       HISTOGRAM_TAIL(3)
+                       break;
+               case BC_RGB_FLOAT:
+                       HISTOGRAM_HEAD(float)
+                       r = (int)(row[0] * 0xffff);
+                       g = (int)(row[1] * 0xffff);
+                       b = (int)(row[2] * 0xffff);
+                       HISTOGRAM_TAIL(3)
+                       break;
+               case BC_YUV888:
+                       HISTOGRAM_HEAD(unsigned char)
+                       y = row[0]; u = row[1]; v = row[2];
+                       YUV::yuv.yuv_to_rgb_8(r, g, b, y, u, v);
+                       HISTOGRAM_TAIL(3)
+                       break;
+               case BC_RGBA8888:
+                       HISTOGRAM_HEAD(unsigned char)
+                       r = row[0]; g = row[1]; b = row[2];
+                       HISTOGRAM_TAIL(4)
+                       break;
+               case BC_RGBA_FLOAT:
+                       HISTOGRAM_HEAD(float)
+                       r = (int)(row[0] * 0xffff);
+                       g = (int)(row[1] * 0xffff);
+                       b = (int)(row[2] * 0xffff);
+                       HISTOGRAM_TAIL(4)
+                       break;
+               case BC_YUVA8888:
+                       HISTOGRAM_HEAD(unsigned char)
+                       y = row[0]; u = row[1]; v = row[2];
+                       YUV::yuv.yuv_to_rgb_8(r, g, b, y, u, v);
+                       HISTOGRAM_TAIL(4)
+                       break;
+               case BC_RGB161616:
+                       HISTOGRAM_HEAD(uint16_t)
+                       r = row[0]; g = row[1]; b = row[2];
+                       HISTOGRAM_TAIL(3)
+                       break;
+               case BC_YUV161616:
+                       HISTOGRAM_HEAD(uint16_t)
+                       y = row[0]; u = row[1]; v = row[2];
+                       YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
+                       HISTOGRAM_TAIL(3)
+                       break;
+               case BC_RGBA16161616:
+                       HISTOGRAM_HEAD(uint16_t)
+                       r = row[0]; g = row[1]; b = row[2];
+                       HISTOGRAM_TAIL(3)
+                       break;
+               case BC_YUVA16161616:
+                       HISTOGRAM_HEAD(uint16_t)
+                       y = row[0]; u = row[1]; v = row[2];
+                       YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
+                       HISTOGRAM_TAIL(4)
+                       break;
                }
        }
        else
-       if(server->operation == HistogramEngine::APPLY)
-       {
-
-
+       if( server->operation == HistogramEngine::APPLY ) {
 
 #define PROCESS(type, components) \
 { \
-       for(int i = pkg->start; i < pkg->end; i++) \
-       { \
+       for( int i=pkg->start; i<pkg->end; ++i ) { \
                type *row = (type*)input->get_rows()[i]; \
-               for(int j = 0; j < w; j++) \
-               { \
+               for( int j=0; j<w; ++j ) { \
                        if ( plugin->config.split && ((j + i * w / h) < w) ) \
-                       continue; \
+                               continue; \
                        row[0] = lookup_r[row[0]]; \
                        row[1] = lookup_g[row[1]]; \
                        row[2] = lookup_b[row[2]]; \
@@ -731,49 +677,22 @@ void HistogramUnit::process_package(LoadPackage *package)
 
 #define PROCESS_YUV(type, components, max) \
 { \
-       for(int i = pkg->start; i < pkg->end; i++) \
-       { \
+       for( int i=pkg->start; i<pkg->end; ++i ) { \
                type *row = (type*)input->get_rows()[i]; \
-               for(int j = 0; j < w; j++) \
-               { \
+               for( int j=0; j<w; ++j ) { \
                        if ( plugin->config.split && ((j + i * w / h) < w) ) \
-                       continue; \
-/* Convert to 16 bit RGB */ \
-                       if(max == 0xff) \
-                       { \
-                               y = (row[0] << 8) | row[0]; \
-                               u = (row[1] << 8) | row[1]; \
-                               v = (row[2] << 8) | row[2]; \
-                       } \
+                               continue; \
+                       y = row[0]; u = row[1]; v = row[2]; \
+                       if( max == 0xff ) \
+                               YUV::yuv.yuv_to_rgb_8(r, g, b, y, u, v); \
                        else \
-                       { \
-                               y = row[0]; \
-                               u = row[1]; \
-                               v = row[2]; \
-                       } \
- \
-                       YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v); \
- \
-/* Look up in RGB domain */ \
-                       r = lookup_r[r]; \
-                       g = lookup_g[g]; \
-                       b = lookup_b[b]; \
- \
-/* Convert to 16 bit YUV */ \
-                       YUV::yuv.rgb_to_yuv_16(r, g, b, y, u, v); \
- \
-                       if(max == 0xff) \
-                       { \
-                               row[0] = y >> 8; \
-                               row[1] = u >> 8; \
-                               row[2] = v >> 8; \
-                       } \
+                               YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v); \
+                       r = lookup_r[r]; g = lookup_g[g]; b = lookup_b[b]; \
+                       if( max == 0xff ) \
+                               YUV::yuv.rgb_to_yuv_8(r, g, b, y, u, v); \
                        else \
-                       { \
-                               row[0] = y; \
-                               row[1] = u; \
-                               row[2] = v; \
-                       } \
+                               YUV::yuv.rgb_to_yuv_16(r, g, b, y, u, v); \
+                       row[0] = y; row[1] = u; row[2] = v; \
                        row += components; \
                } \
        } \
@@ -781,25 +700,16 @@ void HistogramUnit::process_package(LoadPackage *package)
 
 #define PROCESS_FLOAT(components) \
 { \
-       for(int i = pkg->start; i < pkg->end; i++) \
-       { \
+       for( int i=pkg->start; i<pkg->end; ++i ) { \
                float *row = (float*)input->get_rows()[i]; \
-               for(int j = 0; j < w; j++) \
-               { \
+               for( int j=0; j<w; ++j ) { \
                        if ( plugin->config.split && ((j + i * w / h) < w) ) \
-                       continue; \
-                       float r = row[0]; \
-                       float g = row[1]; \
-                       float b = row[2]; \
- \
+                               continue; \
+                       float r = row[0], g = row[1], b = row[2]; \
                        r = plugin->calculate_smooth(r, HISTOGRAM_RED); \
                        g = plugin->calculate_smooth(g, HISTOGRAM_GREEN); \
                        b = plugin->calculate_smooth(b, HISTOGRAM_BLUE); \
- \
-                       row[0] = r; \
-                       row[1] = g; \
-                       row[2] = b; \
- \
+                       row[0] = r; row[1] = g; row[2] = b; \
                        row += components; \
                } \
        } \
@@ -813,50 +723,44 @@ void HistogramUnit::process_package(LoadPackage *package)
                int *lookup_g = plugin->lookup[1];
                int *lookup_b = plugin->lookup[2];
                int r, g, b, y, u, v;
-               switch(input->get_color_model())
-               {
-                       case BC_RGB888:
-                               PROCESS(unsigned char, 3)
-                               break;
-                       case BC_RGB_FLOAT:
-                               PROCESS_FLOAT(3);
-                               break;
-                       case BC_RGBA8888:
-                               PROCESS(unsigned char, 4)
-                               break;
-                       case BC_RGBA_FLOAT:
-                               PROCESS_FLOAT(4);
-                               break;
-                       case BC_RGB161616:
-                               PROCESS(uint16_t, 3)
-                               break;
-                       case BC_RGBA16161616:
-                               PROCESS(uint16_t, 4)
-                               break;
-                       case BC_YUV888:
-                               PROCESS_YUV(unsigned char, 3, 0xff)
-                               break;
-                       case BC_YUVA8888:
-                               PROCESS_YUV(unsigned char, 4, 0xff)
-                               break;
-                       case BC_YUV161616:
-                               PROCESS_YUV(uint16_t, 3, 0xffff)
-                               break;
-                       case BC_YUVA16161616:
-                               PROCESS_YUV(uint16_t, 4, 0xffff)
-                               break;
+               switch( input->get_color_model() ) {
+               case BC_RGB888:
+                       PROCESS(unsigned char, 3)
+                       break;
+               case BC_RGB_FLOAT:
+                       PROCESS_FLOAT(3);
+                       break;
+               case BC_RGBA8888:
+                       PROCESS(unsigned char, 4)
+                       break;
+               case BC_RGBA_FLOAT:
+                       PROCESS_FLOAT(4);
+                       break;
+               case BC_RGB161616:
+                       PROCESS(uint16_t, 3)
+                       break;
+               case BC_RGBA16161616:
+                       PROCESS(uint16_t, 4)
+                       break;
+               case BC_YUV888:
+                       PROCESS_YUV(unsigned char, 3, 0xff)
+                       break;
+               case BC_YUVA8888:
+                       PROCESS_YUV(unsigned char, 4, 0xff)
+                       break;
+               case BC_YUV161616:
+                       PROCESS_YUV(uint16_t, 3, 0xffff)
+                       break;
+               case BC_YUVA16161616:
+                       PROCESS_YUV(uint16_t, 4, 0xffff)
+                       break;
                }
        }
 }
 
 
-
-
-
-
 HistogramEngine::HistogramEngine(HistogramMain *plugin,
-       int total_clients,
-       int total_packages)
+               int total_clients, int total_packages)
  : LoadServer(total_clients, total_packages)
 {
        this->plugin = plugin;
@@ -864,26 +768,19 @@ HistogramEngine::HistogramEngine(HistogramMain *plugin,
 
 void HistogramEngine::init_packages()
 {
-       switch(operation) {
-               case HISTOGRAM:
-                       total_size = data->get_h();
-                       break;
-               case APPLY:
-                       total_size = data->get_h();
-                       break;
-       }
-
-       for(int i = 0; i < get_total_packages(); i++) {
+       total_size = data->get_h();
+       for( int i=0,start=0,n=get_total_packages(); i<n; ) {
                HistogramPackage *package = (HistogramPackage*)get_package(i);
-               package->start = total_size * i / get_total_packages();
-               package->end = total_size * (i + 1) / get_total_packages();
+               package->start = start;
+               package->end = start = (total_size * ++i)/ n;
        }
 
+       int bins = plugin->slots * (HISTOGRAM_MAX-HISTOGRAM_MIN)/100;
 // Initialize clients here in case some don't get run.
-       for(int i = 0; i < get_total_clients(); i++) {
+       for( int i=0; i<get_total_clients(); ++i ) {
                HistogramUnit *unit = (HistogramUnit*)get_client(i);
-               for(int i = 0; i < HISTOGRAM_MODES; i++)
-                       bzero(unit->accum[i], sizeof(int) * HISTOGRAM_SLOTS);
+               for( int i=0; i<HISTOGRAM_MODES; ++i )
+                       bzero(unit->accum[i], sizeof(int)*bins);
        }
 
 }