add histogram_bezier plugin
authorGood Guy <[email protected]>
Mon, 29 Feb 2016 17:47:42 +0000 (10:47 -0700)
committerGood Guy <[email protected]>
Mon, 29 Feb 2016 17:47:42 +0000 (10:47 -0700)
21 files changed:
cinelerra-5.0/plugin_defs
cinelerra-5.0/plugins/Makefile
cinelerra-5.0/plugins/histogram_bezier/Makefile
cinelerra-5.0/plugins/histogram_bezier/bistogram.C [new file with mode: 0644]
cinelerra-5.0/plugins/histogram_bezier/bistogram.h [new file with mode: 0644]
cinelerra-5.0/plugins/histogram_bezier/bistogram.inc [new file with mode: 0644]
cinelerra-5.0/plugins/histogram_bezier/bistogramconfig.C [new file with mode: 0644]
cinelerra-5.0/plugins/histogram_bezier/bistogramconfig.h [new file with mode: 0644]
cinelerra-5.0/plugins/histogram_bezier/bistogramconfig.inc [new file with mode: 0644]
cinelerra-5.0/plugins/histogram_bezier/bistogramwindow.C [new file with mode: 0644]
cinelerra-5.0/plugins/histogram_bezier/bistogramwindow.h [new file with mode: 0644]
cinelerra-5.0/plugins/histogram_bezier/bistogramwindow.inc [new file with mode: 0644]
cinelerra-5.0/plugins/histogram_bezier/histogram.C [deleted file]
cinelerra-5.0/plugins/histogram_bezier/histogram.h [deleted file]
cinelerra-5.0/plugins/histogram_bezier/histogram.inc [deleted file]
cinelerra-5.0/plugins/histogram_bezier/histogramconfig.C [deleted file]
cinelerra-5.0/plugins/histogram_bezier/histogramconfig.h [deleted file]
cinelerra-5.0/plugins/histogram_bezier/histogramconfig.inc [deleted file]
cinelerra-5.0/plugins/histogram_bezier/histogramwindow.C [deleted file]
cinelerra-5.0/plugins/histogram_bezier/histogramwindow.h [deleted file]
cinelerra-5.0/plugins/histogram_bezier/histogramwindow.inc [deleted file]

index 41c39b5f3a901ae570701287172c67c925d0fe4d..b07ef2160766287366a2f9fceb55685165f0fb8d 100644 (file)
@@ -16,7 +16,7 @@ transforms := 1080to480 1080to540 720to480 lens perspective photoscale \
 
 plugin_dirs += colors
 colors := brightness bluebanana C41 color3way colorbalance huesaturation \
-       gamma gradient histogram threshold
+       gamma gradient histogram histogram_bezier threshold
 
 plugin_dirs += exotic
 exotic := aging burn dot holo oil edge
index e45c30b5c57e9f7abe83b68f8de7ba0216fd7499..ffbff61197d035b08fad6ef9da29c73160e4c669 100644 (file)
@@ -56,6 +56,7 @@ DIRS = \
        graphic \
        greycstoration \
        histogram \
+       histogram_bezier \
        holo \
        huesaturation \
        interpolate \
index e4fa47eaae47d7caa8b6609304f9312f37f1e1e2..a0f852e90fa3491d3cea0c9945fe66313d638224 100644 (file)
@@ -1,14 +1,14 @@
 include ../../global_config
 
 OBJS = \
-       $(OBJDIR)/histogram.o \
-       $(OBJDIR)/histogramconfig.o \
-       $(OBJDIR)/histogramwindow.o
+       $(OBJDIR)/bistogram.o \
+       $(OBJDIR)/bistogramconfig.o \
+       $(OBJDIR)/bistogramwindow.o
 
-PLUGIN = histogram
+PLUGIN = histogram_bezier
 
 include ../../plugin_config
 
-$(OBJDIR)/histogram.o: histogram.C
-$(OBJDIR)/histogramconfig.o: histogramconfig.C
-$(OBJDIR)/histogramwindow.o: histogramwindow.C
+$(OBJDIR)/bistogram.o: bistogram.C
+$(OBJDIR)/bistogramconfig.o: bistogramconfig.C
+$(OBJDIR)/bistogramwindow.o: bistogramwindow.C
diff --git a/cinelerra-5.0/plugins/histogram_bezier/bistogram.C b/cinelerra-5.0/plugins/histogram_bezier/bistogram.C
new file mode 100644 (file)
index 0000000..6799e31
--- /dev/null
@@ -0,0 +1,914 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#include <math.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "bcdisplayinfo.h"
+#include "bcsignals.h"
+#include "clip.h"
+#include "bchash.h"
+#include "filexml.h"
+#include "bistogram.h"
+#include "bistogramconfig.h"
+#include "bistogramwindow.h"
+#include "keyframe.h"
+#include "language.h"
+#include "loadbalance.h"
+#include "cicolors.h"
+#include "vframe.h"
+
+
+
+class HistogramMain;
+class HistogramEngine;
+class HistogramWindow;
+
+REGISTER_PLUGIN(HistogramMain)
+
+HistogramMain::HistogramMain(PluginServer *server)
+ : PluginVClient(server)
+{
+       
+       engine = 0;
+       for(int i = 0; i < HISTOGRAM_MODES; i++)
+       {
+               lookup[i] = 0;
+               smoothed[i] = 0;
+               linear[i] = 0;
+               accum[i] = 0;
+       }
+       current_point = -1;
+       mode = HISTOGRAM_VALUE;
+       dragging_point = 0;
+       input = 0;
+       output = 0;
+}
+
+HistogramMain::~HistogramMain()
+{
+       
+       for(int i = 0; i < HISTOGRAM_MODES;i++)
+       {
+               delete [] lookup[i];
+               delete [] smoothed[i];
+               delete [] linear[i];
+               delete [] accum[i];
+       }
+       delete engine;
+}
+
+const char* HistogramMain::plugin_title() { return _("Histogram Bezier"); }
+int HistogramMain::is_realtime() { return 1; }
+
+
+NEW_WINDOW_MACRO(HistogramMain, HistogramWindow)
+LOAD_CONFIGURATION_MACRO(HistogramMain, HistogramConfig)
+
+void HistogramMain::render_gui(void *data)
+{
+       if(thread)
+       {
+               calculate_histogram((VFrame*)data);
+
+               if(config.automatic)
+               {
+                       calculate_automatic((VFrame*)data);
+               }
+
+               HistogramWindow *window = (HistogramWindow *)thread->window;
+               window->lock_window("HistogramMain::render_gui");
+               window->update_canvas();
+               if(config.automatic)
+               {
+                       window->update_input();
+               }
+               window->unlock_window();
+       }
+}
+
+void HistogramMain::update_gui()
+{
+       if(thread)
+       {
+               thread->window->lock_window("HistogramMain::update_gui");
+               int reconfigure = load_configuration();
+               if(reconfigure) 
+               {
+                       HistogramWindow *window = (HistogramWindow *)thread->window;
+                       window->update(0);
+                       if(!config.automatic)
+                       {
+                               window->update_input();
+                       }
+               }
+               thread->window->unlock_window();
+       }
+}
+
+
+void HistogramMain::save_data(KeyFrame *keyframe)
+{
+       FileXML output;
+
+// cause data to be stored directly in text
+       output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
+       output.tag.set_title("HISTOGRAM");
+
+       char string[BCTEXTLEN];
+
+
+       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);
+               output.tag.set_property(string, config.output_max[i]);
+//printf("HistogramMain::save_data %d %f %d\n", config.input_min[i], config.input_mid[i], config.input_max[i]);
+       }
+
+       output.tag.set_property("AUTOMATIC", config.automatic);
+       output.tag.set_property("THRESHOLD", config.threshold);
+       output.tag.set_property("SPLIT", config.split);
+       output.tag.set_property("INTERPOLATION", config.smoothMode);
+       output.append_tag();
+       output.tag.set_title("/HISTOGRAM");
+       output.append_tag();
+       output.append_newline();
+
+
+
+
+
+       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)
+               {
+                       output.tag.set_title("POINT");
+                       output.tag.set_property("X", current->x);
+                       output.tag.set_property("Y", current->y);
+                       output.tag.set_property("GRADIENT", current->gradient);
+                       output.tag.set_property("XOFFSET_LEFT", current->xoffset_left);
+                       output.tag.set_property("XOFFSET_RIGHT", current->xoffset_right);
+                       output.append_tag();
+                       output.tag.set_title("/POINT");
+                       output.append_tag();
+                       output.append_newline();
+                       current = NEXT;
+               }
+
+
+               output.tag.set_title("/POINTS");
+               output.append_tag();
+               output.append_newline();
+       }
+
+
+
+
+
+
+       output.terminate_string();
+}
+
+void HistogramMain::read_data(KeyFrame *keyframe)
+{
+       FileXML input;
+
+       input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
+
+       int result = 0;
+       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]);
+//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);
+                                                       }
+                                               }
+                                       }
+
+                               }
+                               current_input_mode++;
+                       }
+               }
+       }
+
+       config.boundaries();
+
+}
+
+float HistogramMain::calculate_linear(float input, 
+       int subscript,
+       int use_value)
+{
+       int done = 0;
+       float output;
+
+       if(input < 0) {
+               output = 0;
+               done = 1;
+       }
+
+       if(input > 1) {
+               output = 1;
+               done = 1;
+       }
+
+       if(!done) {
+
+               float x1 = 0, y1 = 0;
+               float grad1 = 1.0;
+               float x1right = 0;
+               float x2 = 1, y2 = 1;
+               float grad2 = 1.0;
+               float x2left = 0;
+
+// Get 2 points surrounding current position
+               HistogramPoints *points = &config.points[subscript];
+               HistogramPoint *current = points->first;
+               int done = 0;
+               while(current && !done) {
+                       if(current->x > input) {
+                               x2 = current->x;
+                               y2 = current->y;
+                               grad2 = current->gradient;
+                               x2left = current->xoffset_left;
+                               done = 1;
+                       }
+                       else
+                               current = NEXT;
+               }
+
+               current = points->last;
+               done = 0;
+               while(current && !done) {
+                       if(current->x <= input) {
+                               x1 = current->x;
+                               y1 = current->y;
+                               grad1 = current->gradient;
+                               done = 1;
+                               x1right = current->xoffset_right;
+                       }
+                       else
+                               current = PREVIOUS;
+               }
+
+
+
+
+               if(!EQUIV(x2 - x1, 0))
+               {       
+                 if (config.smoothMode == HISTOGRAM_LINEAR)
+                       output = (input - x1) * (y2 - y1) / (x2 - x1) + y1;
+                 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 +
+                        (dx * dx) * (3*dy - 2* grad1*dx - grad2*dx) / (dx * dx) * delx * delx + grad1*delx + y1;
+                 }
+                 else if (config.smoothMode == HISTOGRAM_BEZIER)
+                 {
+                       /* Using standart DeCasteljau algorithm */
+                       float y1right = y1 + grad1 * x1right;
+                       float y2left = y2 + grad2 * x2left;
+
+                       float t = (input - x1) / (x2 - x1);
+
+                       float pointAy = y1 + (y1right - y1) * t;
+                       float pointBy = y1right + (y2left - y1right) * t;
+                       float pointCy = y2left + (y2 - y2left) * t;
+                       float pointABy = pointAy + (pointBy - pointAy) * t;
+                       float pointBCy = pointBy + (pointCy - pointBy) * t;
+                       output = pointABy + (pointBCy - pointABy) * t;
+                 }
+               }
+               else
+// Linear
+                       output = input * y2;
+       }
+
+// Apply value curve
+       if(use_value) {
+               output = calculate_linear(output, HISTOGRAM_VALUE, 0);
+       }
+
+
+       float output_min = config.output_min[subscript];
+       float output_max = config.output_max[subscript];
+
+// Compress output for value followed by channel
+       output = output_min + output * (output_max - output_min);
+       return output;
+}
+
+float HistogramMain::calculate_smooth(float input, int subscript)
+{
+       float x_f = (input - HIST_MIN_INPUT) * HISTOGRAM_SLOTS / 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);
+
+       float smooth1 = smoothed[subscript][x_i1];
+       float smooth2 = smoothed[subscript][x_i2];
+       float result = smooth1 + (smooth2 - smooth1) * (x_f - x_i1);
+       CLAMP(result, 0, 1.0);
+       return result;
+}
+
+
+void HistogramMain::calculate_histogram(VFrame *data)
+{
+
+       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];
+       }
+       engine->process_packages(HistogramEngine::HISTOGRAM, data);
+
+       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);
+               }
+               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];
+                       }
+               }
+       }
+
+// Remove top and bottom from calculations.  Doesn't work in high
+// precision colormodels.
+       for(int i = 0; i < HISTOGRAM_MODES; i++) {
+               accum[i][0] = 0;
+               accum[i][HISTOGRAM_SLOTS - 1] = 0;
+       }
+}
+
+
+void HistogramMain::calculate_automatic(VFrame *data)
+{
+       calculate_histogram(data);
+       config.reset_points();
+
+// Do each channel
+       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;
+               int threshold = (int)(white_fraction * pixels);
+               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++) {
+                       total += accum[j];
+                       if(total >= threshold) {
+                               max_level = (float)j / HISTOGRAM_SLOTS * FLOAT_RANGE + HIST_MIN_INPUT;
+                               break;
+                       }
+               }
+
+// Get slot below 99% of pixels
+               total = 0;
+               for(int j = HISTOGRAM_SLOTS - 1; j >= 0; j--) {
+                       total += accum[j];
+                       if(total >= threshold) {
+                               min_level = (float)j / HISTOGRAM_SLOTS * FLOAT_RANGE + HIST_MIN_INPUT;
+                               break;
+                       }
+               }
+               config.points[i].insert(max_level, 1.0);
+               config.points[i].insert(min_level, 0.0);
+       }
+}
+
+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);
+
+       if(input_ptr->get_rows()[0] != output_ptr->get_rows()[0])
+       {
+               output_ptr->copy_from(input_ptr);
+       }
+
+SET_TRACE
+// Generate tables here.  The same table is used by many packages to render
+// each horizontal stripe.  Need to cover the entire output range in  each
+// table to avoid green borders
+       if( !lookup[0] || !smoothed[0] || !linear[0] || config.automatic)
+               need_reconfigure = 1;
+       if( need_reconfigure ) {
+SET_TRACE
+// Calculate new curves
+               if(config.automatic) {
+                       calculate_automatic(input);
+               }
+SET_TRACE
+
+// Generate transfer tables for integer colormodels.
+               for(int i = 0; i < 3; i++)
+                       tabulate_curve(i, 1);
+SET_TRACE
+       }
+
+// Apply histogram
+       engine->process_packages(HistogramEngine::APPLY, input);
+
+SET_TRACE
+       return 0;
+}
+
+void HistogramMain::tabulate_curve(int subscript, int use_value)
+{
+       int i;
+       if(!lookup[subscript])
+               lookup[subscript] = new int[HISTOGRAM_SLOTS];
+       if(!smoothed[subscript])
+               smoothed[subscript] = new float[HISTOGRAM_SLOTS];
+       if(!linear[subscript])
+               linear[subscript] = new float[HISTOGRAM_SLOTS];
+
+       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;
+               current_linear[i] = calculate_linear(input, subscript, use_value);
+       }
+// Make smooth curve
+       //float prev = 0.0;
+       for(i = 0; i < HISTOGRAM_SLOTS; 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;
+               }
+       }
+}
+
+HistogramPackage::HistogramPackage()
+ : LoadPackage()
+{
+}
+
+HistogramUnit::HistogramUnit(HistogramEngine *server, 
+       HistogramMain *plugin)
+ : LoadClient(server)
+{
+       this->plugin = plugin;
+       this->server = server;
+       for(int i = 0; i < HISTOGRAM_MODES; i++)
+               accum[i] = new int[HISTOGRAM_SLOTS];
+}
+
+HistogramUnit::~HistogramUnit()
+{
+       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)
+       {
+
+#define HISTOGRAM_HEAD(type) \
+{ \
+       for(int i = pkg->start; i < pkg->end; i++) \
+       { \
+               type *row = (type*)data->get_rows()[i]; \
+               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]++; \
+                       row += components; \
+               } \
+       } \
+}
+
+               VFrame *data = server->data;
+               int w = data->get_w();
+//             int h = data->get_h();
+               int *accum_r = accum[HISTOGRAM_RED];
+               int *accum_g = accum[HISTOGRAM_GREEN];
+               int *accum_b = accum[HISTOGRAM_BLUE];
+               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];
+                               plugin->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];
+                               plugin->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];
+                               plugin->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];
+                               plugin->yuv.yuv_to_rgb_16(r, g, b, y, u, v);
+                               HISTOGRAM_TAIL(4)
+                               break;
+               }
+       }
+       else
+       if(server->operation == HistogramEngine::APPLY)
+       {
+
+
+
+#define PROCESS(type, components) \
+{ \
+       for(int i = pkg->start; i < pkg->end; i++) \
+       { \
+               type *row = (type*)input->get_rows()[i]; \
+               for(int j = 0; j < w; j++) \
+               { \
+                       if ( plugin->config.split && ((j + i * w / h) < w) ) \
+                       continue; \
+                       row[0] = lookup_r[row[0]]; \
+                       row[1] = lookup_g[row[1]]; \
+                       row[2] = lookup_b[row[2]]; \
+                       row += components; \
+               } \
+       } \
+}
+
+#define PROCESS_YUV(type, components, max) \
+{ \
+       for(int i = pkg->start; i < pkg->end; i++) \
+       { \
+               type *row = (type*)input->get_rows()[i]; \
+               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]; \
+                       } \
+                       else \
+                       { \
+                               y = row[0]; \
+                               u = row[1]; \
+                               v = row[2]; \
+                       } \
+ \
+                       plugin->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 */ \
+                       plugin->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; \
+                       } \
+                       else \
+                       { \
+                               row[0] = y; \
+                               row[1] = u; \
+                               row[2] = v; \
+                       } \
+                       row += components; \
+               } \
+       } \
+}
+
+#define PROCESS_FLOAT(components) \
+{ \
+       for(int i = pkg->start; i < pkg->end; i++) \
+       { \
+               float *row = (float*)input->get_rows()[i]; \
+               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]; \
+ \
+                       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 += components; \
+               } \
+       } \
+}
+
+
+               VFrame *input = plugin->input;
+//             VFrame *output = plugin->output;
+               int w = input->get_w(), h = input->get_h();
+               int *lookup_r = plugin->lookup[0];
+               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;
+               }
+       }
+}
+
+
+
+
+
+
+HistogramEngine::HistogramEngine(HistogramMain *plugin, 
+       int total_clients, 
+       int total_packages)
+ : LoadServer(total_clients, total_packages)
+{
+       this->plugin = 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++) {
+               HistogramPackage *package = (HistogramPackage*)get_package(i);
+               package->start = total_size * i / get_total_packages();
+               package->end = total_size * (i + 1) / get_total_packages();
+       }
+
+// Initialize clients here in case some don't get run.
+       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);
+       }
+
+}
+
+LoadClient* HistogramEngine::new_client()
+{
+       return new HistogramUnit(this, plugin);
+}
+
+LoadPackage* HistogramEngine::new_package()
+{
+       return new HistogramPackage;
+}
+
+void HistogramEngine::process_packages(int operation, VFrame *data)
+{
+       this->data = data;
+       this->operation = operation;
+       LoadServer::process_packages();
+}
+
+
+
diff --git a/cinelerra-5.0/plugins/histogram_bezier/bistogram.h b/cinelerra-5.0/plugins/histogram_bezier/bistogram.h
new file mode 100644 (file)
index 0000000..659b71d
--- /dev/null
@@ -0,0 +1,138 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#ifndef HISTOGRAM_H
+#define HISTOGRAM_H
+
+
+#include "bistogram.inc"
+#include "bistogramconfig.h"
+#include "bistogramwindow.inc"
+#include "loadbalance.h"
+#include "cicolors.h"
+#include "pluginvclient.h"
+
+
+enum
+{
+  HISTOGRAM_LINEAR,
+  HISTOGRAM_POLYNOMINAL,
+  HISTOGRAM_BEZIER,
+};
+
+
+class HistogramMain : public PluginVClient
+{
+public:
+       HistogramMain(PluginServer *server);
+       ~HistogramMain();
+
+       int process_realtime(VFrame *input_ptr, VFrame *output_ptr);
+       int is_realtime();
+       void save_data(KeyFrame *keyframe);
+       void read_data(KeyFrame *keyframe);
+       void update_gui();
+       void render_gui(void *data);
+
+       PLUGIN_CLASS_MEMBERS(HistogramConfig)
+
+// Convert input to linear output
+       float calculate_linear(float input, int mode, int do_value);
+       float calculate_smooth(float input, int subscript);
+// Convert input to smoothed output by looking up in smooth table.
+       float calculate_curve(float input);
+// Calculate automatic settings
+       void calculate_automatic(VFrame *data);
+// Calculate histogram
+       void calculate_histogram(VFrame *data);
+// Calculate the linear, smoothed, lookup curves
+       void tabulate_curve(int subscript, int use_value);
+
+
+
+       YUV yuv;
+       VFrame *input, *output;
+       HistogramEngine *engine;
+       int *lookup[HISTOGRAM_MODES];
+       float *smoothed[HISTOGRAM_MODES];
+       float *linear[HISTOGRAM_MODES];
+       int *accum[HISTOGRAM_MODES];
+// Input point being dragged or edited
+       int current_point;
+// Current channel being viewed
+       int mode;
+       int dragging_point;
+       int point_x_offset;
+       int point_y_offset;
+};
+
+class HistogramPackage : public LoadPackage
+{
+public:
+       HistogramPackage();
+       int start, end;
+};
+
+class HistogramUnit : public LoadClient
+{
+public:
+       HistogramUnit(HistogramEngine *server, HistogramMain *plugin);
+       ~HistogramUnit();
+       void process_package(LoadPackage *package);
+       HistogramEngine *server;
+       HistogramMain *plugin;
+       int *accum[5];
+};
+
+class HistogramEngine : public LoadServer
+{
+public:
+       HistogramEngine(HistogramMain *plugin, 
+               int total_clients, 
+               int total_packages);
+       void process_packages(int operation, VFrame *data);
+       void init_packages();
+       LoadClient* new_client();
+       LoadPackage* new_package();
+       HistogramMain *plugin;
+       int total_size;
+
+
+       int operation;
+       enum
+       {
+               HISTOGRAM,
+               APPLY
+       };
+       VFrame *data;
+};
+
+
+
+
+
+
+
+
+
+
+
+#endif
diff --git a/cinelerra-5.0/plugins/histogram_bezier/bistogram.inc b/cinelerra-5.0/plugins/histogram_bezier/bistogram.inc
new file mode 100644 (file)
index 0000000..bfbd7e3
--- /dev/null
@@ -0,0 +1,58 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#ifndef HISTOGRAM_INC
+#define HISTOGRAM_INC
+
+
+
+
+
+// modes
+#define HISTOGRAM_MODES 4
+#define HISTOGRAM_RED 0
+#define HISTOGRAM_GREEN 1
+#define HISTOGRAM_BLUE 2
+#define HISTOGRAM_VALUE 3
+
+// Number of divisions in histogram.  
+// 65536 + min and max range to speed up the tabulation
+#define HISTOGRAM_SLOTS 0x13333
+#define FLOAT_RANGE 1.2
+// Minimum value in percentage
+#define HISTOGRAM_MIN -10
+#define HIST_MIN_INPUT -0.1
+// Maximum value in percentage
+#define HISTOGRAM_MAX 110
+#define HIST_MAX_INPUT 1.1
+
+#define PRECISION 0.001
+#define DIGITS 3
+#define THRESHOLD_SCALE 1000
+
+#define BOX_SIZE 10
+
+
+class HistogramEngine;
+class HistogramMain;
+
+
+#endif
diff --git a/cinelerra-5.0/plugins/histogram_bezier/bistogramconfig.C b/cinelerra-5.0/plugins/histogram_bezier/bistogramconfig.C
new file mode 100644 (file)
index 0000000..d84550f
--- /dev/null
@@ -0,0 +1,296 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#include "clip.h"
+#include "bistogramconfig.h"
+#include "units.h"
+
+#include <math.h>
+
+
+
+
+HistogramPoint::HistogramPoint()
+ : ListItem<HistogramPoint>()
+{
+}
+
+HistogramPoint::~HistogramPoint()
+{
+}
+
+int HistogramPoint::equivalent(HistogramPoint *src)
+{
+       return EQUIV(x, src->x) && EQUIV(y, src->y) && EQUIV(gradient, src->gradient);
+}
+
+
+
+
+HistogramPoints::HistogramPoints()
+ : List<HistogramPoint>()
+{
+       insert(0.0,0.0);
+       first->gradient = 1.0;
+       first->xoffset_left = 0.0;
+       first->xoffset_right = 0.05;
+       insert(1.0,1.0);
+       last->gradient = 1.0;  
+       last->xoffset_left = -0.05;
+       last->xoffset_right = 0.0;
+       
+}
+
+HistogramPoints::~HistogramPoints()
+{
+}
+
+HistogramPoint* HistogramPoints::insert(float x, float y)
+{
+       HistogramPoint *current = first;
+
+// Get existing point after new point
+       while(current)
+       {
+               if(current->x > x)
+                       break;
+               else
+                       current = NEXT;
+       }
+
+// Insert new point before current point
+       HistogramPoint *new_point = new HistogramPoint;
+       if(current)
+       {
+               insert_before(current, new_point);
+       }
+       else
+// Append new point to list
+       {
+               append(new_point);
+       }
+
+       new_point->x = x;
+       new_point->y = y;
+       new_point->xoffset_left = -0.05;
+       new_point->xoffset_right = 0.05;
+
+
+       return new_point;
+}
+
+void HistogramPoints::boundaries()
+{
+       HistogramPoint *current = first;
+       while(current)
+       {
+               CLAMP(current->x, 0.0, 1.0);
+               CLAMP(current->y, 0.0, 1.0);
+               current = NEXT;
+       }
+}
+
+int HistogramPoints::equivalent(HistogramPoints *src)
+{
+       HistogramPoint *current_this = first;
+       HistogramPoint *current_src = src->first;
+       while(current_this && current_src)
+       {
+               if(!current_this->equivalent(current_src)) return 0;
+               current_this = current_this->next;
+               current_src = current_src->next;
+       }
+
+       return !current_this ^ !current_src ? 0 : 1;
+}
+
+void HistogramPoints::copy_from(HistogramPoints *src)
+{
+       while(last)
+               delete last;
+       HistogramPoint *current = src->first;
+       while(current)
+       {
+               HistogramPoint *new_point = new HistogramPoint;
+               new_point->x = current->x;
+               new_point->y = current->y;
+               append(new_point);
+               current = NEXT;
+       }
+}
+
+void HistogramPoints::interpolate(HistogramPoints *prev, 
+       HistogramPoints *next,
+       double prev_scale,
+       double next_scale)
+{
+       HistogramPoint *current = first;
+       HistogramPoint *current_prev = prev->first;
+       HistogramPoint *current_next = next->first;
+
+       while(current && current_prev && current_next)
+       {
+               current->x = current_prev->x * prev_scale +
+                       current_next->x * next_scale;
+               current->y = current_prev->y * prev_scale +
+                       current_next->y * next_scale;
+               current = NEXT;
+               current_prev = current_prev->next;
+               current_next = current_next->next;
+       }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+HistogramConfig::HistogramConfig()
+{
+       reset(1);
+}
+
+void HistogramConfig::reset(int do_mode)
+{
+       reset_points();
+
+       
+       for(int i = 0; i < HISTOGRAM_MODES; i++)
+       {
+               output_min[i] = 0.0;
+               output_max[i] = 1.0;
+       }
+
+       if(do_mode) 
+       {
+               automatic = 0;
+               threshold = 0.1;
+               split = 0;
+               smoothMode = 0;
+       }
+}
+
+void HistogramConfig::reset_points()
+{
+       for(int i = 0; i < HISTOGRAM_MODES; i++)
+       {
+               while(points[i].last) delete points[i].last;
+               points[i].insert(0.0,0.0);
+               points[i].last->gradient = 1.0;
+               points[i].insert(1.0,1.0);
+               points[i].last->gradient = 1.0;
+       }
+}
+
+
+void HistogramConfig::boundaries()
+{
+       for(int i = 0; i < HISTOGRAM_MODES; i++)
+       {
+               points[i].boundaries();
+               CLAMP(output_min[i], HIST_MIN_INPUT, HIST_MAX_INPUT);
+               CLAMP(output_max[i], HIST_MIN_INPUT, HIST_MAX_INPUT);
+               output_min[i] = Units::quantize(output_min[i], PRECISION);
+               output_max[i] = Units::quantize(output_max[i], PRECISION);
+       }
+       CLAMP(threshold, 0, 1);
+}
+
+int HistogramConfig::equivalent(HistogramConfig &that)
+{
+       for(int i = 0; i < HISTOGRAM_MODES; i++)
+       {
+               if(!points[i].equivalent(&that.points[i]) ||
+                       !EQUIV(output_min[i], that.output_min[i]) ||
+                       !EQUIV(output_max[i], that.output_max[i])) return 0;
+       }
+
+       if(automatic != that.automatic ||
+               !EQUIV(threshold, that.threshold)) return 0;
+
+       return 1;
+}
+
+void HistogramConfig::copy_from(HistogramConfig &that)
+{
+       for(int i = 0; i < HISTOGRAM_MODES; i++)
+       {
+               points[i].copy_from(&that.points[i]);
+               output_min[i] = that.output_min[i];
+               output_max[i] = that.output_max[i];
+       }
+
+       automatic = that.automatic;
+       threshold = that.threshold;
+       split = that.split;
+       smoothMode = that.smoothMode;
+}
+
+void HistogramConfig::interpolate(HistogramConfig &prev, 
+       HistogramConfig &next, 
+       int64_t prev_frame, 
+       int64_t next_frame, 
+       int64_t current_frame)
+{
+       double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
+       double prev_scale = 1.0 - next_scale;
+
+       for(int i = 0; i < HISTOGRAM_MODES; i++)
+       {
+               points[i].interpolate(&prev.points[i], &next.points[i], next_scale, prev_scale);
+               output_min[i] = prev.output_min[i] * prev_scale + next.output_min[i] * next_scale;
+               output_max[i] = prev.output_max[i] * prev_scale + next.output_max[i] * next_scale;
+       }
+
+       threshold = prev.threshold * prev_scale + next.threshold * next_scale;
+       automatic = prev.automatic;
+       split = prev.split;
+       smoothMode = prev.smoothMode;
+}
+
+
+void HistogramConfig::dump()
+{
+       for(int j = 0; j < HISTOGRAM_MODES; j++)
+       {
+               printf("HistogramConfig::dump mode=%d\n", j);
+               HistogramPoints *points = &this->points[j];
+               HistogramPoint *current = points->first;
+               while(current)
+               {
+                       printf("%f,%f ", current->x, current->y);
+                       fflush(stdout);
+                       current = NEXT;
+               }
+               printf("\n");
+       }
+}
+
+
+
diff --git a/cinelerra-5.0/plugins/histogram_bezier/bistogramconfig.h b/cinelerra-5.0/plugins/histogram_bezier/bistogramconfig.h
new file mode 100644 (file)
index 0000000..ce4d490
--- /dev/null
@@ -0,0 +1,96 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#ifndef HISTOGRAMCONFIG_H
+#define HISTOGRAMCONFIG_H
+
+
+#include "bistogram.inc"
+#include "bistogramconfig.inc"
+#include "linklist.h"
+#include <stdint.h>
+
+class HistogramPoint : public ListItem<HistogramPoint>
+{
+public:
+       HistogramPoint();
+       ~HistogramPoint();
+
+       int equivalent(HistogramPoint *src);
+       float x, y;
+       float gradient;
+       float xoffset_left;
+       float xoffset_right;
+};
+
+
+class HistogramPoints : public List<HistogramPoint>
+{
+public:
+       HistogramPoints();
+       ~HistogramPoints();
+
+// Insert new point
+       HistogramPoint* insert(float x, float y);
+       int equivalent(HistogramPoints *src);
+       void boundaries();
+       void copy_from(HistogramPoints *src);
+       void interpolate(HistogramPoints *prev, 
+               HistogramPoints *next,
+               double prev_scale,
+               double next_scale);
+};
+
+class HistogramConfig
+{
+public:
+       HistogramConfig();
+
+       int equivalent(HistogramConfig &that);
+       void copy_from(HistogramConfig &that);
+       void interpolate(HistogramConfig &prev, 
+               HistogramConfig &next, 
+               int64_t prev_frame, 
+               int64_t next_frame, 
+               int64_t current_frame);
+// Used by constructor and reset button
+       void reset(int do_mode);
+       void reset_points();
+       void boundaries();
+       void dump();
+
+// Range 0 - 1.0
+// Input points
+       HistogramPoints points[HISTOGRAM_MODES];
+// Output points
+       float output_min[HISTOGRAM_MODES];
+       float output_max[HISTOGRAM_MODES];
+       int automatic;
+       float threshold;
+       int split;
+       int smoothMode;
+};
+
+
+#endif
+
+
+
diff --git a/cinelerra-5.0/plugins/histogram_bezier/bistogramconfig.inc b/cinelerra-5.0/plugins/histogram_bezier/bistogramconfig.inc
new file mode 100644 (file)
index 0000000..de38650
--- /dev/null
@@ -0,0 +1,31 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#ifndef HISTOGRAMCONFIG_INC
+#define HISTOGRAMCONFIG_INC
+
+
+class HistogramPoint;
+class HistogramPoints;
+class HistogramConfig;
+
+
+#endif
diff --git a/cinelerra-5.0/plugins/histogram_bezier/bistogramwindow.C b/cinelerra-5.0/plugins/histogram_bezier/bistogramwindow.C
new file mode 100644 (file)
index 0000000..55046ec
--- /dev/null
@@ -0,0 +1,1056 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#include "bcdisplayinfo.h"
+#include "bcsignals.h"
+#include "bistogram.h"
+#include "bistogramconfig.h"
+#include "bistogramwindow.h"
+#include "keys.h"
+#include "language.h"
+
+
+#include <unistd.h>
+#include <string.h>
+
+HistogramWindow::HistogramWindow(HistogramMain *plugin)
+ : PluginClientWindow(plugin, 440, 480, 440, 480, 0)
+{
+       this->plugin = plugin;
+}
+
+HistogramWindow::~HistogramWindow()
+{
+}
+
+#include "min_picon_png.h"
+#include "mid_picon_png.h"
+#include "max_picon_png.h"
+static VFramePng max_picon_image(max_picon_png);
+static VFramePng mid_picon_image(mid_picon_png);
+static VFramePng min_picon_image(min_picon_png);
+
+void HistogramWindow::create_objects()
+{
+       int x = 10, y = 10, x1 = 10;
+       BC_Title *title = 0;
+
+       max_picon = create_pixmap(&max_picon_image);
+       mid_picon = create_pixmap(&mid_picon_image);
+       min_picon = create_pixmap(&min_picon_image);
+       add_subwindow(mode_v = new HistogramMode(plugin, 
+               x, 
+               y,
+               HISTOGRAM_VALUE,
+               _("Value")));
+       x += 70;
+       add_subwindow(mode_r = new HistogramMode(plugin, 
+               x, 
+               y,
+               HISTOGRAM_RED,
+               _("Red")));
+       x += 70;
+       add_subwindow(mode_g = new HistogramMode(plugin, 
+               x, 
+               y,
+               HISTOGRAM_GREEN,
+               _("Green")));
+       x += 70;
+       add_subwindow(mode_b = new HistogramMode(plugin, 
+               x, 
+               y,
+               HISTOGRAM_BLUE,
+               _("Blue")));
+//     x += 70;
+//     add_subwindow(mode_a = new HistogramMode(plugin, 
+//             x, 
+//             y,
+//             HISTOGRAM_ALPHA,
+//             _("Alpha")));
+
+       x = x1;
+       y += 30;
+       add_subwindow(title = new BC_Title(x, y, _("Input X:")));
+       x += title->get_w() + 10;
+       input_x = new HistogramInputText(plugin,
+               this,
+               x,
+               y,
+               1);
+       input_x->create_objects();
+
+       x += input_x->get_w() + 10;
+       add_subwindow(title = new BC_Title(x, y, _("Input Y:")));
+       x += title->get_w() + 10;
+       input_y = new HistogramInputText(plugin,
+               this,
+               x,
+               y,
+               0);
+       input_y->create_objects();
+
+       y += 30;
+       x = x1;
+
+       canvas_w = get_w() - x - x;
+       canvas_h = get_h() - y - 170;
+       title1_x = x;
+       title2_x = x + (int)(canvas_w * -HIST_MIN_INPUT / FLOAT_RANGE);
+       title3_x = x + (int)(canvas_w * (1.0 - HIST_MIN_INPUT) / FLOAT_RANGE);
+       title4_x = x + (int)(canvas_w);
+       add_subwindow(canvas = new HistogramCanvas(plugin,
+               this,
+               x, 
+               y, 
+               canvas_w, 
+               canvas_h));
+       draw_canvas_overlay();
+       canvas->flash();
+
+       y += canvas->get_h() + 1;
+       add_subwindow(new BC_Title(title1_x, 
+               y, 
+               "-10%"));
+       add_subwindow(new BC_Title(title2_x,
+               y,
+               "0%"));
+       add_subwindow(new BC_Title(title3_x - get_text_width(MEDIUMFONT, "100"),
+               y,
+               "100%"));
+       add_subwindow(new BC_Title(title4_x - get_text_width(MEDIUMFONT, "110"),
+               y,
+               "110%"));
+
+       y += 20;
+       add_subwindow(title = new BC_Title(x, y, _("Output min:")));
+       x += title->get_w() + 10;
+       output_min = new HistogramOutputText(plugin,
+               this,
+               x,
+               y,
+               &plugin->config.output_min[plugin->mode]);
+       output_min->create_objects();
+       x += output_min->get_w() + 10;
+       add_subwindow(new BC_Title(x, y, _("Output Max:")));
+       x += title->get_w() + 10;
+       output_max = new HistogramOutputText(plugin,
+               this,
+               x,
+               y,
+               &plugin->config.output_max[plugin->mode]);
+       output_max->create_objects();
+
+       x = x1;
+       y += 30;
+
+       add_subwindow(output = new HistogramSlider(plugin, 
+               this,
+               x, 
+               y, 
+               get_w() - 20,
+               30,
+               0));
+       output->update();
+       y += 40;
+
+
+       add_subwindow(automatic = new HistogramAuto(plugin, 
+               x, 
+               y));
+
+       x += 120;
+       add_subwindow(new HistogramReset(plugin, 
+               x, 
+               y));
+       x += 100;
+       add_subwindow(new BC_Title(x, y, _("Threshold:")));
+       x += 100;
+       threshold = new HistogramOutputText(plugin,
+               this,
+               x,
+               y,
+               &plugin->config.threshold);
+       threshold->create_objects();
+       x = x1;
+       y += 40;        
+       add_subwindow(split = new HistogramSplit(plugin, x, y));
+       y += 6;
+       x += 150;
+       add_subwindow(new BC_Title(x,y, _("Interpolation:")));
+       x += 120;
+       add_subwindow(smoothModeChoser = new HistogramSmoothMode(plugin, this, x, y));
+       smoothModeChoser->create_objects();
+
+       show_window();
+}
+
+int HistogramWindow::keypress_event()
+{
+       int result = 0;
+       if(get_keypress() == BACKSPACE ||
+               get_keypress() == DELETE)
+       {
+               if(plugin->current_point >= 0)
+               {
+                       HistogramPoint *current = 
+                               plugin->config.points[plugin->mode].get_item_number(plugin->current_point);
+                       delete current;
+                       plugin->current_point = -1;
+                       update_input();
+                       update_canvas();
+                       plugin->send_configure_change();
+                       result = 1;
+               }
+       }
+       return result;
+}
+
+void HistogramWindow::update(int do_input)
+{
+       automatic->update(plugin->config.automatic);
+       threshold->update(plugin->config.threshold);
+       update_mode();
+
+       if(do_input) update_input();
+       update_output();
+}
+
+void HistogramWindow::update_input()
+{
+       input_x->update();
+       input_y->update();
+}
+
+void HistogramWindow::update_output()
+{
+       output->update();
+       output_min->update(plugin->config.output_min[plugin->mode]);
+       output_max->update(plugin->config.output_max[plugin->mode]);
+}
+
+void HistogramWindow::update_mode()
+{
+       mode_v->update(plugin->mode == HISTOGRAM_VALUE ? 1 : 0);
+       mode_r->update(plugin->mode == HISTOGRAM_RED ? 1 : 0);
+       mode_g->update(plugin->mode == HISTOGRAM_GREEN ? 1 : 0);
+       mode_b->update(plugin->mode == HISTOGRAM_BLUE ? 1 : 0);
+       output_min->output = &plugin->config.output_min[plugin->mode];
+       output_max->output = &plugin->config.output_max[plugin->mode];
+}
+
+void HistogramWindow::draw_canvas_overlay()
+{
+       canvas->set_color(0x00ff00);
+       int y1;
+
+// Calculate output curve
+       plugin->tabulate_curve(plugin->mode, 0);
+
+// Draw output line
+       for(int i = 0; i < canvas_w; i++)
+       {
+               float input = (float)i / 
+                               canvas_w * 
+                               FLOAT_RANGE + 
+                               HIST_MIN_INPUT;
+               float output = plugin->calculate_smooth(input, plugin->mode);
+
+               int y2 = canvas_h - (int)(output * canvas_h);
+               if(i > 0)
+               {
+                       canvas->draw_line(i - 1, y1, i, y2);
+               }
+               y1 = y2;
+       }
+
+// Draw output points
+       HistogramPoint *current = plugin->config.points[plugin->mode].first;
+       int number = 0;
+       while(current)
+       {
+               int x = (int)((current->x - HIST_MIN_INPUT) * canvas_w / FLOAT_RANGE);
+               int y = (int)(canvas_h - current->y * canvas_h);
+               if(number == plugin->current_point)
+                       canvas->draw_box(x - BOX_SIZE / 2, y - BOX_SIZE / 2, BOX_SIZE, BOX_SIZE);
+               else
+                       canvas->draw_rectangle(x - BOX_SIZE / 2, y - BOX_SIZE / 2, BOX_SIZE, BOX_SIZE);
+                       
+//Draw gradients
+       if (plugin->config.smoothMode > HISTOGRAM_LINEAR)
+       {       
+               int x1,x2,y1,y2;
+               canvas->set_color(0x0000ff);
+               x2 = (int)((current->x + current->xoffset_right - HIST_MIN_INPUT) * canvas_w / FLOAT_RANGE);
+               x1 = (int)((current->x + current->xoffset_left - HIST_MIN_INPUT) * canvas_w / FLOAT_RANGE);
+               y2 = (int)(canvas_h - (current->y + current->xoffset_right * current->gradient) * canvas_h);
+               y1 = (int)(canvas_h - (current->y + current->xoffset_left * current->gradient) * canvas_h);
+/*             x2 = x + (title3_x - title2_x)/20;
+               x1 = x - (title3_x - title2_x)/20;
+               y1 = y + (int)(current->gradient * (float)(canvas_h)/20.0);
+               y2 = y - (int)(current->gradient * (float)(canvas_h)/20.0);
+//             int y2 = (int)(canvas_h - canvas_h * (current->y + current->gradient /10));*/
+               canvas->draw_line(x1,y1,x2,y2);
+               
+               canvas->draw_circle(x1 - BOX_SIZE / 4, y1 - BOX_SIZE / 4, BOX_SIZE/2, BOX_SIZE/2);
+               canvas->draw_circle(x2 - BOX_SIZE / 4, y2 - BOX_SIZE / 4, BOX_SIZE/2, BOX_SIZE/2);
+               canvas->set_color(0x00ff00);
+       }
+                               
+               current = NEXT;
+               number++;
+       }
+
+
+// Draw 0 and 100% lines.
+       canvas->set_color(0xff0000);
+       canvas->draw_line(title2_x - canvas->get_x(),
+               0, 
+               title2_x - canvas->get_x(), 
+               canvas_h);
+       canvas->draw_line(title3_x - canvas->get_x(), 
+               0, 
+               title3_x - canvas->get_x(), 
+               canvas_h);
+}
+
+void HistogramWindow::update_canvas()
+{
+       int *accum = plugin->accum[plugin->mode];
+       int accum_per_canvas_i = HISTOGRAM_SLOTS / canvas_w + 1;
+       float accum_per_canvas_f = (float)HISTOGRAM_SLOTS / canvas_w;
+       int normalize = 0;
+       int max = 0;
+
+       for(int i = 0; i < HISTOGRAM_SLOTS; i++)
+       {
+               if(accum && accum[i] > normalize) normalize = accum[i];
+       }
+
+
+       if(normalize)
+       {
+               for(int i = 0; i < canvas_w; i++)
+               {
+                       int accum_start = (int)(accum_per_canvas_f * i);
+                       int accum_end = accum_start + accum_per_canvas_i;
+                       max = 0;
+                       for(int j = accum_start; j < accum_end; j++)
+                       {
+                               max = MAX(accum[j], max);
+                       }
+
+//                     max = max * canvas_h / normalize;
+                       max = (int)(log(max) / log(normalize) * canvas_h);
+
+                       canvas->set_color(0xffffff);
+                       canvas->draw_line(i, 0, i, canvas_h - max);
+                       canvas->set_color(0x000000);
+                       canvas->draw_line(i, canvas_h - max, i, canvas_h);
+               }
+       }
+       else
+       {
+               canvas->set_color(0xffffff);
+               canvas->draw_box(0, 0, canvas_w, canvas_h);
+       }
+
+
+       draw_canvas_overlay();
+       canvas->flash();
+}
+
+
+
+
+
+
+
+
+HistogramCanvas::HistogramCanvas(HistogramMain *plugin,
+       HistogramWindow *gui,
+       int x,
+       int y,
+       int w,
+       int h)
+ : BC_SubWindow(x,
+       y,
+       w,
+       h,
+       0xffffff)
+{
+       this->plugin = plugin;
+       this->gui = gui;
+}
+
+int HistogramCanvas::button_press_event()
+{
+       int result = 0;
+       if(is_event_win() && cursor_inside())
+       {
+               if(!plugin->dragging_point)
+               {
+                       HistogramPoint *new_point = 0;
+                       gui->deactivate();
+// Search for existing point under cursor
+                       HistogramPoint *current = plugin->config.points[plugin->mode].first;
+                       plugin->current_point = -1;
+                       int dragID = 0;
+                       while(current)
+                       {
+                               int x = (int)((current->x - HIST_MIN_INPUT) * gui->canvas_w / FLOAT_RANGE);
+                               int y = (int)(gui->canvas_h - current->y * gui->canvas_h);
+
+/* Check for click on main point */
+                               if(get_cursor_x() >= x - BOX_SIZE / 2 &&
+                                       get_cursor_y() >= y - BOX_SIZE / 2 &&
+                                       get_cursor_x() < x + BOX_SIZE / 2 &&
+                                       get_cursor_y() < y + BOX_SIZE / 2)
+                               {
+                                       plugin->current_point = 
+                                               plugin->config.points[plugin->mode].number_of(current);
+                                       plugin->point_x_offset = get_cursor_x() - x;
+                                       plugin->point_y_offset = get_cursor_y() - y;
+                                       dragID = 1;
+                                       break;
+                               }
+                               if (plugin->config.smoothMode == HISTOGRAM_LINEAR)
+                                 break;
+
+                               int xright = 
+                                 (int)((current->x + current->xoffset_right - HIST_MIN_INPUT) * gui->canvas_w / FLOAT_RANGE);
+                               int yright = 
+                                 (int)(gui->canvas_h - (current->y + current->xoffset_right * current->gradient) * 
+                                 gui->canvas_h);
+
+/* Check for click on right handle */                          
+                               if(get_cursor_x() >= xright - BOX_SIZE / 2 &&
+                                  get_cursor_y() >= yright - BOX_SIZE / 2 &&
+                                  get_cursor_x() <  xright + BOX_SIZE / 2 &&
+                                  get_cursor_y() <  yright + BOX_SIZE / 2)
+                               {
+                                       plugin->current_point =
+                                               plugin->config.points[plugin->mode].number_of(current);
+                                       plugin->point_x_offset = get_cursor_x() - xright;
+                                       plugin->point_y_offset = get_cursor_y() - yright;
+                                       dragID = 2;
+                                       break;
+                               }
+                               
+/* Check for click on left handle */
+                               int xleft = 
+                                 (int)((current->x + current->xoffset_left - HIST_MIN_INPUT) * gui->canvas_w / FLOAT_RANGE);
+                               int yleft = 
+                                 (int)(gui->canvas_h - (current->y + current->xoffset_left * current->gradient) * 
+                                 gui->canvas_h);
+                               if(get_cursor_x() >= xleft - BOX_SIZE / 2 &&
+                                  get_cursor_y() >= yleft - BOX_SIZE / 2 &&
+                                  get_cursor_x() <  xleft + BOX_SIZE / 2 &&
+                                  get_cursor_y() <  yleft + BOX_SIZE / 2)
+                               {
+                                       plugin->current_point =
+                                               plugin->config.points[plugin->mode].number_of(current);
+                                       plugin->point_x_offset = get_cursor_x() - xleft;
+                                       plugin->point_y_offset = get_cursor_y() - yleft;
+                                       dragID = 3;
+                                       break;
+                               }
+
+
+                               current = NEXT;
+                       }
+
+                       if(plugin->current_point < 0)
+                       {
+// Create new point under cursor
+                               float current_x = (float)get_cursor_x() * 
+                                       FLOAT_RANGE / 
+                                       get_w() + 
+                                       HIST_MIN_INPUT;
+                               float current_y = 1.0 - 
+                                       (float)get_cursor_y() / 
+                                       get_h();
+                               new_point = 
+                                       plugin->config.points[plugin->mode].insert(current_x, current_y);
+                               plugin->current_point = 
+                                       plugin->config.points[plugin->mode].number_of(new_point);
+                               plugin->point_x_offset = 0;
+                               plugin->point_y_offset = 0;
+                               
+// Default gradient            
+// Get 2 points surrounding current position
+                               float x1,x2,y1,y2;
+
+                               HistogramPoint *current = plugin->config.points[plugin->mode].first;
+                               int done = 0;
+                               while(current && !done)
+                               {
+                                       if(current->x > current_x)
+                                       {
+                                               x2 = current->x;
+                                               y2 = current->y;
+                                               done = 1;
+                                       }
+                                       else
+                                               current = NEXT;
+                               }
+               
+                               current = plugin->config.points[plugin->mode].last;
+                               done = 0;
+                               while(current && !done)
+                               {
+                                       if(current->x <= current_x)
+                                       {
+                                               x1 = current->x;
+                                               y1 = current->y;
+                                               done = 1;
+                                       }
+                                       else
+                                               current = PREVIOUS;
+                               }
+                               new_point->gradient = (y2 - y1) / (x2 - x1);
+                               dragID = 1;
+                                               
+                       }
+                       
+
+                       plugin->dragging_point = dragID;
+                       result = 1;
+
+                       plugin->config.boundaries();
+                       gui->update_input();
+                       gui->update_canvas();
+                       if(new_point)
+                       {
+                               plugin->send_configure_change();
+                       }
+               }
+       }
+       return result;
+}
+
+int HistogramCanvas::cursor_motion_event()
+{
+       if(plugin->dragging_point)
+       {
+               HistogramPoint * current_point = plugin->config.points[plugin->mode].get_item_number(plugin->current_point);
+
+               float current_x = 
+                       (float)(get_cursor_x() - plugin->point_x_offset) * 
+                       FLOAT_RANGE / 
+                       get_w() + 
+                       HIST_MIN_INPUT;
+               float current_y = 1.0 - 
+                       (float)(get_cursor_y() - plugin->point_y_offset) / 
+                       get_h();
+
+               switch(plugin->dragging_point)
+               {
+                 case 1: /* Main point dragged */  
+                       current_point->x = current_x;
+                       current_point->y = current_y;
+                       break;
+                 case 2: /* Right control point dragged */
+                       if (current_x - current_point->x > 0)
+                       {
+                         current_point->xoffset_right = current_x - current_point->x;
+                         current_point->gradient = (current_y - current_point->y) / (current_x - current_point->x);
+                       }
+                       break;
+                 case 3: /* Left control point dragged */
+                       if (current_x - current_point->x < 0)
+                       {
+                         current_point->xoffset_left = current_x - current_point->x;
+                         current_point->gradient = (current_point->y - current_y) / (current_point->x - current_x);
+                       }
+                       break;
+               }
+                 
+               plugin->config.boundaries();
+               gui->update_input();
+               gui->update_canvas();
+               plugin->send_configure_change();
+               return 1;
+       }
+       return 0;
+}
+
+int HistogramCanvas::button_release_event()
+{
+       if(plugin->dragging_point)
+       {
+// Test for out of order points to delete.
+               HistogramPoint *current = 
+                       plugin->config.points[plugin->mode].get_item_number(plugin->current_point);
+               HistogramPoint *prev = PREVIOUS;
+               HistogramPoint *next = NEXT;
+
+               if((prev && prev->x >= current->x) ||
+                       (next && next->x <= current->x))
+               {
+                       delete current;
+                       plugin->current_point = -1;
+                       plugin->config.boundaries();
+                       gui->update_input();
+                       gui->update_canvas();
+                       plugin->send_configure_change();
+               }
+
+               plugin->dragging_point = 0;
+       }
+       return 0;
+}
+
+
+
+
+
+
+
+HistogramReset::HistogramReset(HistogramMain *plugin, 
+       int x,
+       int y)
+ : BC_GenericButton(x, y, _("Reset"))
+{
+       this->plugin = plugin;
+}
+int HistogramReset::handle_event()
+{
+       plugin->config.reset(0);
+       HistogramWindow *window = (HistogramWindow *)plugin->thread->window;
+       window->update(1);
+       window->update_canvas();
+       plugin->send_configure_change();
+       return 1;
+}
+
+
+
+
+
+
+
+
+
+HistogramSlider::HistogramSlider(HistogramMain *plugin, 
+       HistogramWindow *gui,
+       int x, 
+       int y, 
+       int w,
+       int h,
+       int is_input)
+ : BC_SubWindow(x, y, w, h)
+{
+       this->plugin = plugin;
+       this->gui = gui;
+       this->is_input = is_input;
+       operation = NONE;
+}
+
+int HistogramSlider::input_to_pixel(float input)
+{
+       return (int)((input - HIST_MIN_INPUT) / FLOAT_RANGE * get_w());
+}
+
+int HistogramSlider::button_press_event()
+{
+       if(is_event_win() && cursor_inside())
+       {
+//             int w = get_w();
+               int h = get_h();
+               int half_h = get_h() / 2;
+
+               gui->deactivate();
+
+               if(operation == NONE)
+               {
+                       int x1 = input_to_pixel(plugin->config.output_min[plugin->mode]) - 
+                               gui->mid_picon->get_w() / 2;
+                       int x2 = x1 + gui->mid_picon->get_w();
+                       if(get_cursor_x() >= x1 && get_cursor_x() < x2 &&
+                               get_cursor_y() >= half_h && get_cursor_y() < h)
+                       {
+                               operation = DRAG_MIN_OUTPUT;
+                       }
+               }
+
+               if(operation == NONE)
+               {
+                       int x1 = input_to_pixel(plugin->config.output_max[plugin->mode]) - 
+                               gui->mid_picon->get_w() / 2;
+                       int x2 = x1 + gui->mid_picon->get_w();
+                       if(get_cursor_x() >= x1 && get_cursor_x() < x2 &&
+                               get_cursor_y() >= half_h && get_cursor_y() < h)
+                       {
+                               operation = DRAG_MAX_OUTPUT;
+                       }
+               }
+               return 1;
+       }
+       return 0;
+}
+
+int HistogramSlider::button_release_event()
+{
+       if(operation != NONE)
+       {
+               operation = NONE;
+               return 1;
+       }
+       return 0;
+}
+
+int HistogramSlider::cursor_motion_event()
+{
+       if(operation != NONE)
+       {
+               float value = (float)get_cursor_x() / get_w() * FLOAT_RANGE + HIST_MIN_INPUT;
+               CLAMP(value, HIST_MIN_INPUT, HIST_MAX_INPUT);
+
+               switch(operation)
+               {
+                       case DRAG_MIN_OUTPUT:
+                               value = MIN(plugin->config.output_max[plugin->mode], value);
+                               plugin->config.output_min[plugin->mode] = value;
+                               break;
+                       case DRAG_MAX_OUTPUT:
+                               value = MAX(plugin->config.output_min[plugin->mode], value);
+                               plugin->config.output_max[plugin->mode] = value;
+                               break;
+               }
+       
+               plugin->config.boundaries();
+               gui->update_output();
+
+               plugin->send_configure_change();
+               return 1;
+       }
+       return 0;
+}
+
+void HistogramSlider::update()
+{
+       int w = get_w();
+       int h = get_h();
+       int half_h = get_h() / 2;
+//     int quarter_h = get_h() / 4;
+       int mode = plugin->mode;
+       int r = 0xff;
+       int g = 0xff;
+       int b = 0xff;
+
+       clear_box(0, 0, w, h);
+
+       switch(mode)
+       {
+               case HISTOGRAM_RED:
+                       g = b = 0x00;
+                       break;
+               case HISTOGRAM_GREEN:
+                       r = b = 0x00;
+                       break;
+               case HISTOGRAM_BLUE:
+                       r = g = 0x00;
+                       break;
+       }
+
+       for(int i = 0; i < w; i++)
+       {
+               int color = (int)(i * 0xff / w);
+               set_color(((r * color / 0xff) << 16) | 
+                       ((g * color / 0xff) << 8) | 
+                       (b * color / 0xff));
+
+               draw_line(i, 0, i, half_h);
+       }
+
+       float min;
+       float max;
+       min = plugin->config.output_min[plugin->mode];
+       max = plugin->config.output_max[plugin->mode];
+
+       draw_pixmap(gui->min_picon,
+               input_to_pixel(min) - gui->min_picon->get_w() / 2,
+               half_h + 1);
+       draw_pixmap(gui->max_picon,
+               input_to_pixel(max) - gui->max_picon->get_w() / 2,
+               half_h + 1);
+
+       flash();
+       flush();
+}
+
+
+
+
+
+
+
+
+
+HistogramAuto::HistogramAuto(HistogramMain *plugin, 
+       int x, 
+       int y)
+ : BC_CheckBox(x, y, plugin->config.automatic, _("Automatic"))
+{
+       this->plugin = plugin;
+}
+
+int HistogramAuto::handle_event()
+{
+       plugin->config.automatic = get_value();
+       plugin->send_configure_change();
+       return 1;
+}
+
+
+
+
+HistogramSplit::HistogramSplit(HistogramMain *plugin, 
+       int x, 
+       int y)
+ : BC_CheckBox(x, y, plugin->config.split, _("Split picture"))
+{
+       this->plugin = plugin;
+}
+
+int HistogramSplit::handle_event()
+{
+       plugin->config.split = get_value();
+       plugin->send_configure_change();
+       return 1;
+}
+
+
+
+
+HistogramMode::HistogramMode(HistogramMain *plugin, 
+       int x, 
+       int y,
+       int value,
+       char *text)
+ : BC_Radial(x, y, plugin->mode == value, text)
+{
+       this->plugin = plugin;
+       this->value = value;
+}
+int HistogramMode::handle_event()
+{
+       plugin->mode = value;
+       plugin->current_point= -1;
+       HistogramWindow *window = (HistogramWindow *)plugin->thread->window;
+       window->update_canvas();
+       window->update_mode();
+       window->update_input();
+       window->update_canvas();
+       window->update_output();
+       window->output->update();
+//     plugin->send_configure_change();
+       return 1;
+}
+
+
+
+
+
+
+
+
+
+HistogramOutputText::HistogramOutputText(HistogramMain *plugin,
+       HistogramWindow *gui,
+       int x,
+       int y,
+       float *output)
+ : BC_TumbleTextBox(gui, 
+               output ? (float)*output : 0.0,
+               (float)HIST_MIN_INPUT,
+               (float)HIST_MAX_INPUT,
+               x, 
+               y, 
+               60)
+{
+       this->plugin = plugin;
+       this->output = output;
+       set_precision(DIGITS);
+       set_increment(PRECISION);
+}
+
+
+int HistogramOutputText::handle_event()
+{
+       if(output)
+       {
+               *output = atof(get_text());
+       }
+
+       HistogramWindow *window = (HistogramWindow *)plugin->thread->window;
+       window->output->update();
+       plugin->send_configure_change();
+       return 1;
+}
+
+
+
+
+
+
+
+
+HistogramInputText::HistogramInputText(HistogramMain *plugin,
+       HistogramWindow *gui,
+       int x,
+       int y,
+       int do_x)
+ : BC_TumbleTextBox(gui, 
+               0.0,
+               (float)HIST_MIN_INPUT,
+               (float)HIST_MAX_INPUT,
+               x, 
+               y, 
+               60)
+{
+       this->do_x = do_x;
+       this->plugin = plugin;
+       this->gui = gui;
+       set_precision(DIGITS);
+       set_increment(PRECISION);
+}
+
+
+int HistogramInputText::handle_event()
+{
+       if(plugin->current_point >= 0 &&
+               plugin->current_point < plugin->config.points[plugin->mode].total())
+       {
+               HistogramPoint *point = 
+                       plugin->config.points[plugin->mode].get_item_number(
+                               plugin->current_point);
+
+               if(point)
+               {
+                       if(do_x) 
+                               point->x = atof(get_text());
+                       else
+                               point->y = atof(get_text());
+
+                       plugin->config.boundaries();
+                       gui->update_canvas();
+
+                       HistogramWindow *window = (HistogramWindow *)plugin->thread->window;
+                       window->output->update();
+                       plugin->send_configure_change();
+               }
+       }
+       return 1;
+}
+
+void HistogramInputText::update()
+{
+       if(plugin->current_point >= 0 &&
+               plugin->current_point < plugin->config.points[plugin->mode].total())
+       {
+               HistogramPoint *point = 
+
+                       plugin->config.points[plugin->mode].get_item_number(
+                               plugin->current_point);
+
+               if(point)
+               {
+                       if(do_x)
+                               BC_TumbleTextBox::update(point->x);
+                       else
+                               BC_TumbleTextBox::update(point->y);
+               }
+               else
+               {
+                       BC_TumbleTextBox::update((float)0.0);
+               }
+       }
+       else
+       {
+               BC_TumbleTextBox::update((float)0.0);
+       }
+       
+}
+
+
+HistogramSmoothMode::HistogramSmoothMode(HistogramMain*plugin, 
+       HistogramWindow *gui, 
+       int x, 
+       int y)
+ : BC_PopupMenu(x, y, 120, to_text(plugin->config.smoothMode), 1)
+{
+       this->plugin = plugin;
+       this->gui = gui;
+}
+void HistogramSmoothMode::create_objects()
+{
+       add_item(new BC_MenuItem(to_text(HISTOGRAM_LINEAR)));
+       add_item(new BC_MenuItem(to_text(HISTOGRAM_POLYNOMINAL)));
+       add_item(new BC_MenuItem(to_text(HISTOGRAM_BEZIER)));
+}
+
+char* HistogramSmoothMode::to_text(int mode)
+{
+       switch(mode)
+       {
+               case HISTOGRAM_LINEAR:
+                       return _("Linear");
+               case HISTOGRAM_POLYNOMINAL:
+                       return _("Polynominal");
+               case HISTOGRAM_BEZIER:
+                       return _("Bezier");
+       }
+       return _("None");
+}
+
+int HistogramSmoothMode::from_text(char *text)
+{
+       if(!strcmp(text, to_text(HISTOGRAM_LINEAR))) 
+               return HISTOGRAM_LINEAR;
+       if(!strcmp(text, to_text(HISTOGRAM_POLYNOMINAL))) 
+               return HISTOGRAM_POLYNOMINAL;
+       if(!strcmp(text, to_text(HISTOGRAM_BEZIER))) 
+               return HISTOGRAM_BEZIER;
+       return HISTOGRAM_LINEAR;
+}
+
+int HistogramSmoothMode::handle_event()
+{
+       plugin->config.smoothMode = from_text(get_text());
+       gui->update_canvas();
+       plugin->send_configure_change();
+       return 1;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cinelerra-5.0/plugins/histogram_bezier/bistogramwindow.h b/cinelerra-5.0/plugins/histogram_bezier/bistogramwindow.h
new file mode 100644 (file)
index 0000000..dbc8565
--- /dev/null
@@ -0,0 +1,204 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#ifndef HISTOGRAMWINDOW_H
+#define HISTOGRAMWINDOW_H
+
+
+
+#include "bistogram.inc"
+#include "bistogramwindow.inc"
+#include "pluginvclient.h"
+
+
+class HistogramSmoothMode : public BC_PopupMenu
+{
+public:
+       HistogramSmoothMode(HistogramMain *client, 
+               HistogramWindow *window, 
+               int x, 
+               int y);
+       void create_objects();
+       static char* to_text(int shape);
+       static int from_text(char *text);
+       int handle_event();
+       HistogramMain *plugin;
+       HistogramWindow *gui;
+};
+
+class HistogramSlider : public BC_SubWindow
+{
+public:
+       HistogramSlider(HistogramMain *plugin, 
+               HistogramWindow *gui,
+               int x, 
+               int y, 
+               int w,
+               int h,
+               int is_input);
+
+       void update();
+       int button_press_event();
+       int button_release_event();
+       int cursor_motion_event();
+       int input_to_pixel(float input);
+
+       int operation;
+       enum
+       {
+               NONE,
+               DRAG_INPUT,
+               DRAG_MIN_OUTPUT,
+               DRAG_MAX_OUTPUT,
+       };
+       int is_input;
+       HistogramMain *plugin;
+       HistogramWindow *gui;
+};
+
+class HistogramAuto : public BC_CheckBox
+{
+public:
+       HistogramAuto(HistogramMain *plugin, 
+               int x, 
+               int y);
+       int handle_event();
+       HistogramMain *plugin;
+};
+
+class HistogramSplit : public BC_CheckBox
+{
+public:
+       HistogramSplit(HistogramMain *plugin, 
+               int x, 
+               int y);
+       int handle_event();
+       HistogramMain *plugin;
+};
+
+class HistogramMode : public BC_Radial
+{
+public:
+       HistogramMode(HistogramMain *plugin, 
+               int x, 
+               int y,
+               int value,
+               char *text);
+       int handle_event();
+       HistogramMain *plugin;
+       int value;
+};
+
+class HistogramReset : public BC_GenericButton
+{
+public:
+       HistogramReset(HistogramMain *plugin, 
+               int x,
+               int y);
+       int handle_event();
+       HistogramMain *plugin;
+};
+
+
+class HistogramOutputText : public BC_TumbleTextBox
+{
+public:
+       HistogramOutputText(HistogramMain *plugin,
+               HistogramWindow *gui,
+               int x,
+               int y,
+               float *output);
+       int handle_event();
+       HistogramMain *plugin;
+       float *output;
+};
+
+class HistogramInputText : public BC_TumbleTextBox
+{
+public:
+       HistogramInputText(HistogramMain *plugin,
+               HistogramWindow *gui,
+               int x,
+               int y,
+               int do_x);
+
+       int handle_event();
+       void update();
+
+       HistogramMain *plugin;
+       HistogramWindow *gui;
+       int do_x;
+};
+
+class HistogramCanvas : public BC_SubWindow
+{
+public:
+       HistogramCanvas(HistogramMain *plugin,
+               HistogramWindow *gui,
+               int x,
+               int y,
+               int w,
+               int h);
+       int button_press_event();
+       int cursor_motion_event();
+       int button_release_event();
+       HistogramMain *plugin;
+       HistogramWindow *gui;
+};
+
+class HistogramWindow : public PluginClientWindow
+{
+public:
+       HistogramWindow(HistogramMain *plugin);
+       ~HistogramWindow();
+
+       void create_objects();
+       void update(int do_input);
+       void update_mode();
+       void update_canvas();
+       void draw_canvas_overlay();
+       void update_input();
+       void update_output();
+       int keypress_event();
+
+       HistogramSlider *output;
+       HistogramAuto *automatic;
+       HistogramSplit *split;
+       HistogramSmoothMode *smoothModeChoser;
+       HistogramMode *mode_v, *mode_r, *mode_g, *mode_b /*,  *mode_a */;
+       HistogramOutputText *output_min;
+       HistogramOutputText *output_max;
+       HistogramOutputText *threshold;
+       HistogramInputText *input_x;
+       HistogramInputText *input_y;
+       HistogramCanvas *canvas;
+       HistogramMain *plugin;
+       int canvas_w;
+       int canvas_h;
+       int title1_x;
+       int title2_x;
+       int title3_x;
+       int title4_x;
+       BC_Pixmap *max_picon, *mid_picon, *min_picon;
+};
+
+
+#endif
diff --git a/cinelerra-5.0/plugins/histogram_bezier/bistogramwindow.inc b/cinelerra-5.0/plugins/histogram_bezier/bistogramwindow.inc
new file mode 100644 (file)
index 0000000..cc9e113
--- /dev/null
@@ -0,0 +1,28 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#ifndef HISTOGRAMWINDOW_INC
+#define HISTOGRAMWINDOW_INC
+
+class HistogramWindow;
+class HistogramThread;
+
+#endif
diff --git a/cinelerra-5.0/plugins/histogram_bezier/histogram.C b/cinelerra-5.0/plugins/histogram_bezier/histogram.C
deleted file mode 100644 (file)
index 72af090..0000000
+++ /dev/null
@@ -1,1124 +0,0 @@
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
- */
-
-#include <math.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "bcdisplayinfo.h"
-#include "bcsignals.h"
-#include "clip.h"
-#include "bchash.h"
-#include "filexml.h"
-#include "histogram.h"
-#include "histogramconfig.h"
-#include "histogramwindow.h"
-#include "keyframe.h"
-#include "language.h"
-#include "loadbalance.h"
-#include "cicolors.h"
-#include "vframe.h"
-
-
-
-class HistogramMain;
-class HistogramEngine;
-class HistogramWindow;
-
-
-
-
-
-REGISTER_PLUGIN(HistogramMain)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-HistogramMain::HistogramMain(PluginServer *server)
- : PluginVClient(server)
-{
-       
-       engine = 0;
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
-               lookup[i] = 0;
-               smoothed[i] = 0;
-               linear[i] = 0;
-               accum[i] = 0;
-       }
-       current_point = -1;
-       mode = HISTOGRAM_VALUE;
-       dragging_point = 0;
-       input = 0;
-       output = 0;
-}
-
-HistogramMain::~HistogramMain()
-{
-       
-       for(int i = 0; i < HISTOGRAM_MODES;i++)
-       {
-               delete [] lookup[i];
-               delete [] smoothed[i];
-               delete [] linear[i];
-               delete [] accum[i];
-       }
-       delete engine;
-}
-
-char* HistogramMain::plugin_title() { return _("Histogram"); }
-int HistogramMain::is_realtime() { return 1; }
-
-
-
-SHOW_GUI_MACRO(HistogramMain, HistogramThread)
-
-SET_STRING_MACRO(HistogramMain)
-
-RAISE_WINDOW_MACRO(HistogramMain)
-
-LOAD_CONFIGURATION_MACRO(HistogramMain, HistogramConfig)
-
-void HistogramMain::render_gui(void *data)
-{
-       if(thread)
-       {
-               calculate_histogram((VFrame*)data);
-
-               if(config.automatic)
-               {
-                       calculate_automatic((VFrame*)data);
-               }
-
-               thread->window->lock_window("HistogramMain::render_gui");
-               thread->window->update_canvas();
-               if(config.automatic)
-               {
-                       thread->window->update_input();
-               }
-               thread->window->unlock_window();
-       }
-}
-
-void HistogramMain::update_gui()
-{
-       if(thread)
-       {
-               thread->window->lock_window("HistogramMain::update_gui");
-               int reconfigure = load_configuration();
-               if(reconfigure) 
-               {
-                       thread->window->update(0);
-                       if(!config.automatic)
-                       {
-                               thread->window->update_input();
-                       }
-               }
-               thread->window->unlock_window();
-       }
-}
-
-
-int HistogramMain::load_defaults()
-{
-       char directory[BCTEXTLEN], string[BCTEXTLEN];
-// set the default directory
-       sprintf(directory, "%shistogram.rc", BCASTDIR);
-
-// load the defaults
-       defaults = new BC_Hash(directory);
-       defaults->load();
-
-       for(int j = 0; j < HISTOGRAM_MODES; j++)
-       {
-               while(config.points[j].last) delete config.points[j].last;
-
-               sprintf(string, "TOTAL_POINTS_%d", j);
-               int total_points = defaults->get(string, 0);
-
-               for(int i = 0; i < total_points; i++)
-               {
-                       HistogramPoint *point = new HistogramPoint;
-                       sprintf(string, "INPUT_X_%d_%d", j, i);
-                       point->x = defaults->get(string, point->x);
-                       sprintf(string, "INPUT_Y_%d_%d", j, i);
-                       point->y = defaults->get(string, point->y);
-                       sprintf(string, "GRADIENT_%d_%d", j, i);
-                       point->gradient = defaults->get(string, point->gradient);
-                       sprintf(string, "XOFFSET_LEFT_%d_%d", j, i);
-                       point->xoffset_left = defaults->get(string, point->xoffset_left);
-                       sprintf(string, "XOFFSET_RIGHT_%d_%d", j, i);
-                       point->xoffset_right = defaults->get(string, point->xoffset_right);
-                       config.points[j].append(point);
-               }
-       }
-
-
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
-               sprintf(string, "OUTPUT_MIN_%d", i);
-               config.output_min[i] = defaults->get(string, config.output_min[i]);
-               sprintf(string, "OUTPUT_MAX_%d", i);
-               config.output_max[i] = defaults->get(string, config.output_max[i]);
-       }
-
-       config.automatic = defaults->get("AUTOMATIC", config.automatic);
-       mode = defaults->get("MODE", mode);
-       CLAMP(mode, 0, HISTOGRAM_MODES - 1);
-       config.threshold = defaults->get("THRESHOLD", config.threshold);
-       config.split = defaults->get("SPLIT", config.split);
-       config.smoothMode = defaults->get("INTERPOLATION", config.smoothMode);
-       config.boundaries();
-       return 0;
-}
-
-
-int HistogramMain::save_defaults()
-{
-       char string[BCTEXTLEN];
-
-
-
-       for(int j = 0; j < HISTOGRAM_MODES; j++)
-       {
-               int total_points = config.points[j].total();
-               sprintf(string, "TOTAL_POINTS_%d", j);
-               defaults->update(string, total_points);
-               HistogramPoint *current = config.points[j].first;
-               int number = 0;
-               while(current)
-               {
-                       sprintf(string, "INPUT_X_%d_%d", j, number);
-                       defaults->update(string, current->x);
-                       sprintf(string, "INPUT_Y_%d_%d", j, number);
-                       defaults->update(string, current->y);
-                       sprintf(string, "GRADIENT_%d_%d", j, number);
-                       defaults->update(string, current->gradient);
-                       sprintf(string, "XOFFSET_LEFT_%d_%d", j, number);
-                       defaults->update(string, current->xoffset_left);
-                       sprintf(string, "XOFFSET_RIGHT_%d_%d", j, number);
-                       defaults->update(string, current->xoffset_right);                       
-                       current = NEXT;
-                       number++;
-               }
-       }
-
-
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
-               sprintf(string, "OUTPUT_MIN_%d", i);
-               defaults->update(string, config.output_min[i]);
-               sprintf(string, "OUTPUT_MAX_%d", i);
-               defaults->update(string, config.output_max[i]);
-       }
-
-       defaults->update("AUTOMATIC", config.automatic);
-       defaults->update("MODE", mode);
-       defaults->update("THRESHOLD", config.threshold);
-       defaults->update("SPLIT", config.split);
-       defaults->update("INTERPOLATION", config.smoothMode);
-       defaults->save();
-       return 0;
-}
-
-
-
-void HistogramMain::save_data(KeyFrame *keyframe)
-{
-       FileXML output;
-
-// cause data to be stored directly in text
-       output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
-       output.tag.set_title("HISTOGRAM");
-
-       char string[BCTEXTLEN];
-
-
-       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);
-               output.tag.set_property(string, config.output_max[i]);
-//printf("HistogramMain::save_data %d %f %d\n", config.input_min[i], config.input_mid[i], config.input_max[i]);
-       }
-
-       output.tag.set_property("AUTOMATIC", config.automatic);
-       output.tag.set_property("THRESHOLD", config.threshold);
-       output.tag.set_property("SPLIT", config.split);
-       output.tag.set_property("INTERPOLATION", config.smoothMode);
-       output.append_tag();
-       output.append_newline();
-
-
-
-
-
-       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)
-               {
-                       output.tag.set_title("POINT");
-                       output.tag.set_property("X", current->x);
-                       output.tag.set_property("Y", current->y);
-                       output.tag.set_property("GRADIENT", current->gradient);
-                       output.tag.set_property("XOFFSET_LEFT", current->xoffset_left);
-                       output.tag.set_property("XOFFSET_RIGHT", current->xoffset_right);
-                       output.append_tag();
-                       output.append_newline();
-                       current = NEXT;
-               }
-
-
-               output.tag.set_title("/POINTS");
-               output.append_tag();
-               output.append_newline();
-       }
-
-
-
-
-
-
-       output.terminate_string();
-}
-
-void HistogramMain::read_data(KeyFrame *keyframe)
-{
-       FileXML input;
-
-       input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
-
-       int result = 0;
-       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]);
-//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);
-                                                       }
-                                               }
-                                       }
-
-                               }
-                               current_input_mode++;
-                       }
-               }
-       }
-
-       config.boundaries();
-
-}
-
-float HistogramMain::calculate_linear(float input, 
-       int subscript,
-       int use_value)
-{
-       int done = 0;
-       float output;
-
-       if(input < 0)
-       {
-               output = 0;
-               done = 1;
-       }
-
-       if(input > 1)
-       {
-               output = 1;
-               done = 1;
-       }
-
-       if(!done)
-       {
-
-               float x1 = 0;
-               float y1 = 0;
-               float grad1 = 1.0;
-               float x1right = 0;
-               float x2 = 1;
-               float y2 = 1;
-               float grad2 = 1.0;
-               float x2left = 0;
-
-
-
-// Get 2 points surrounding current position
-               HistogramPoints *points = &config.points[subscript];
-               HistogramPoint *current = points->first;
-               int done = 0;
-               while(current && !done)
-               {
-                       if(current->x > input)
-                       {
-                               x2 = current->x;
-                               y2 = current->y;
-                               grad2 = current->gradient;
-                               x2left = current->xoffset_left;
-                               done = 1;
-                       }
-                       else
-                               current = NEXT;
-               }
-
-               current = points->last;
-               done = 0;
-               while(current && !done)
-               {
-                       if(current->x <= input)
-                       {
-                               x1 = current->x;
-                               y1 = current->y;
-                               grad1 = current->gradient;
-                               done = 1;
-                               x1right = current->xoffset_right;
-                       }
-                       else
-                               current = PREVIOUS;
-               }
-
-
-
-
-               if(!EQUIV(x2 - x1, 0))
-               {       
-                 if (config.smoothMode == HISTOGRAM_LINEAR)
-                       output = (input - x1) * (y2 - y1) / (x2 - x1) + y1;
-                 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 = 1 / (dx * dx * dx) * (grad2 * dx + grad1 * dx - 2*dy) * delx * delx * delx + 1 / (dx * dx) * (3*dy - 2* grad1*dx - grad2*dx) * delx * delx + grad1*delx + y1;
-                 }
-                 else if (config.smoothMode == HISTOGRAM_BEZIER)
-                 {
-                       /* Using standart DeCasteljau algorithm */
-                       float y1right = y1 + grad1 * x1right;
-                       float y2left = y2 + grad2 * x2left;
-
-                       float t = (input - x1) / (x2 - x1);
-
-                       float pointAy = y1 + (y1right - y1) * t;
-                       float pointBy = y1right + (y2left - y1right) * t;
-                       float pointCy = y2left + (y2 - y2left) * t;
-                       float pointABy = pointAy + (pointBy - pointAy) * t;
-                       float pointBCy = pointBy + (pointCy - pointBy) * t;
-                       output = pointABy + (pointBCy - pointABy) * t;
-                       
-                       }
-               }
-                       
-               else
-// Linear
-                       output = input * y2;
-
-
-
-// 
-
-
-       }
-
-// Apply value curve
-       if(use_value)
-       {
-               output = calculate_linear(output, HISTOGRAM_VALUE, 0);
-       }
-
-
-       float output_min = config.output_min[subscript];
-       float output_max = config.output_max[subscript];
-       float output_left;
-       float output_right;
-       float output_linear;
-
-// Compress output for value followed by channel
-       output = output_min + 
-               output * 
-               (output_max - output_min);
-
-
-       return output;
-}
-
-float HistogramMain::calculate_smooth(float input, int subscript)
-{
-       float x_f = (input - HIST_MIN_INPUT) * HISTOGRAM_SLOTS / 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);
-
-       float smooth1 = smoothed[subscript][x_i1];
-       float smooth2 = smoothed[subscript][x_i2];
-       float result = smooth1 + (smooth2 - smooth1) * (x_f - x_i1);
-       CLAMP(result, 0, 1.0);
-       return result;
-}
-
-
-void HistogramMain::calculate_histogram(VFrame *data)
-{
-
-       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];
-       }
-       engine->process_packages(HistogramEngine::HISTOGRAM, data);
-
-       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);
-               }
-               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];
-                       }
-               }
-       }
-
-// Remove top and bottom from calculations.  Doesn't work in high
-// precision colormodels.
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
-               accum[i][0] = 0;
-               accum[i][HISTOGRAM_SLOTS - 1] = 0;
-       }
-}
-
-
-void HistogramMain::calculate_automatic(VFrame *data)
-{
-       calculate_histogram(data);
-       config.reset_points();
-
-// Do each channel
-       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;
-               int threshold = (int)(white_fraction * pixels);
-               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++)
-               {
-                       total += accum[j];
-                       if(total >= threshold)
-                       {
-                               max_level = (float)j / HISTOGRAM_SLOTS * FLOAT_RANGE + HIST_MIN_INPUT;
-                               break;
-                       }
-               }
-
-// Get slot below 99% of pixels
-               total = 0;
-               for(int j = HISTOGRAM_SLOTS - 1; j >= 0; j--)
-               {
-                       total += accum[j];
-                       if(total >= threshold)
-                       {
-                               min_level = (float)j / HISTOGRAM_SLOTS * FLOAT_RANGE + HIST_MIN_INPUT;
-                               break;
-                       }
-               }
-
-
-               config.points[i].insert(max_level, 1.0);
-               config.points[i].insert(min_level, 0.0);
-
-       }
-}
-
-
-
-
-
-
-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);
-
-       if(input_ptr->get_rows()[0] != output_ptr->get_rows()[0])
-       {
-               output_ptr->copy_from(input_ptr);
-       }
-
-SET_TRACE
-// Generate tables here.  The same table is used by many packages to render
-// each horizontal stripe.  Need to cover the entire output range in  each
-// table to avoid green borders
-       if(need_reconfigure || 
-               !lookup[0] || 
-               !smoothed[0] || 
-               !linear[0] || 
-               config.automatic)
-       {
-SET_TRACE
-// Calculate new curves
-               if(config.automatic)
-               {
-                       calculate_automatic(input);
-               }
-SET_TRACE
-
-// Generate transfer tables for integer colormodels.
-               for(int i = 0; i < 3; i++)
-                       tabulate_curve(i, 1);
-SET_TRACE
-       }
-
-
-
-
-// Apply histogram
-       engine->process_packages(HistogramEngine::APPLY, input);
-
-SET_TRACE
-
-       return 0;
-}
-
-void HistogramMain::tabulate_curve(int subscript, int use_value)
-{
-       int i;
-       if(!lookup[subscript])
-               lookup[subscript] = new int[HISTOGRAM_SLOTS];
-       if(!smoothed[subscript])
-               smoothed[subscript] = new float[HISTOGRAM_SLOTS];
-       if(!linear[subscript])
-               linear[subscript] = new float[HISTOGRAM_SLOTS];
-
-       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;
-               current_linear[i] = calculate_linear(input, subscript, use_value);
-       }
-
-
-
-
-
-
-// Make smooth curve
-       float prev = 0.0;
-       for(i = 0; i < HISTOGRAM_SLOTS; 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;
-               }
-       }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-HistogramPackage::HistogramPackage()
- : LoadPackage()
-{
-}
-
-
-
-
-HistogramUnit::HistogramUnit(HistogramEngine *server, 
-       HistogramMain *plugin)
- : LoadClient(server)
-{
-       this->plugin = plugin;
-       this->server = server;
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-               accum[i] = new int[HISTOGRAM_SLOTS];
-}
-
-HistogramUnit::~HistogramUnit()
-{
-       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)
-       {
-
-#define HISTOGRAM_HEAD(type) \
-{ \
-       for(int i = pkg->start; i < pkg->end; i++) \
-       { \
-               type *row = (type*)data->get_rows()[i]; \
-               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); \
-                       CLAMP(g, 0, HISTOGRAM_SLOTS); \
-                       CLAMP(b, 0, HISTOGRAM_SLOTS); \
-                       CLAMP(v, 0, HISTOGRAM_SLOTS); \
-                       accum_r[r]++; \
-                       accum_g[g]++; \
-                       accum_b[b]++; \
-                       accum_v[v]++; \
-                       row += components; \
-               } \
-       } \
-}
-
-
-
-
-               VFrame *data = server->data;
-               int w = data->get_w();
-               int h = data->get_h();
-               int *accum_r = accum[HISTOGRAM_RED];
-               int *accum_g = accum[HISTOGRAM_GREEN];
-               int *accum_b = accum[HISTOGRAM_BLUE];
-               int *accum_v = accum[HISTOGRAM_VALUE];
-               int r, g, b, a, 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];
-                               plugin->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];
-                               plugin->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];
-                               plugin->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];
-                               plugin->yuv.yuv_to_rgb_16(r, g, b, y, u, v);
-                               HISTOGRAM_TAIL(4)
-                               break;
-               }
-       }
-       else
-       if(server->operation == HistogramEngine::APPLY)
-       {
-
-
-
-#define PROCESS(type, components) \
-{ \
-       for(int i = pkg->start; i < pkg->end; i++) \
-       { \
-               type *row = (type*)input->get_rows()[i]; \
-               for(int j = 0; j < w; j++) \
-               { \
-                       if ( plugin->config.split && ((j + i * w / h) < w) ) \
-                       continue; \
-                       row[0] = lookup_r[row[0]]; \
-                       row[1] = lookup_g[row[1]]; \
-                       row[2] = lookup_b[row[2]]; \
-                       row += components; \
-               } \
-       } \
-}
-
-#define PROCESS_YUV(type, components, max) \
-{ \
-       for(int i = pkg->start; i < pkg->end; i++) \
-       { \
-               type *row = (type*)input->get_rows()[i]; \
-               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]; \
-                       } \
-                       else \
-                       { \
-                               y = row[0]; \
-                               u = row[1]; \
-                               v = row[2]; \
-                       } \
- \
-                       plugin->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 */ \
-                       plugin->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; \
-                       } \
-                       else \
-                       { \
-                               row[0] = y; \
-                               row[1] = u; \
-                               row[2] = v; \
-                       } \
-                       row += components; \
-               } \
-       } \
-}
-
-#define PROCESS_FLOAT(components) \
-{ \
-       for(int i = pkg->start; i < pkg->end; i++) \
-       { \
-               float *row = (float*)input->get_rows()[i]; \
-               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]; \
- \
-                       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 += components; \
-               } \
-       } \
-}
-
-
-               VFrame *input = plugin->input;
-               VFrame *output = plugin->output;
-               int w = input->get_w();
-               int h = input->get_h();
-               int *lookup_r = plugin->lookup[0];
-               int *lookup_g = plugin->lookup[1];
-               int *lookup_b = plugin->lookup[2];
-               int r, g, b, y, u, v, a;
-               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)
- : LoadServer(total_clients, total_packages)
-{
-       this->plugin = plugin;
-}
-
-void HistogramEngine::init_packages()
-{
-       switch(operation)
-       {
-               case HISTOGRAM:
-                       total_size = data->get_h();
-                       break;
-               case APPLY:
-                       total_size = data->get_h();
-                       break;
-       }
-
-
-       int package_size = (int)((float)total_size / 
-                       get_total_packages() + 1);
-       int start = 0;
-
-       for(int i = 0; i < get_total_packages(); i++)
-       {
-               HistogramPackage *package = (HistogramPackage*)get_package(i);
-               package->start = total_size * i / get_total_packages();
-               package->end = total_size * (i + 1) / get_total_packages();
-       }
-
-// Initialize clients here in case some don't get run.
-       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);
-       }
-
-}
-
-LoadClient* HistogramEngine::new_client()
-{
-       return new HistogramUnit(this, plugin);
-}
-
-LoadPackage* HistogramEngine::new_package()
-{
-       return new HistogramPackage;
-}
-
-void HistogramEngine::process_packages(int operation, VFrame *data)
-{
-       this->data = data;
-       this->operation = operation;
-       LoadServer::process_packages();
-}
-
-
-
diff --git a/cinelerra-5.0/plugins/histogram_bezier/histogram.h b/cinelerra-5.0/plugins/histogram_bezier/histogram.h
deleted file mode 100644 (file)
index afb8fb0..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
- */
-
-#ifndef HISTOGRAM_H
-#define HISTOGRAM_H
-
-
-#include "histogram.inc"
-#include "histogramconfig.h"
-#include "histogramwindow.inc"
-#include "loadbalance.h"
-#include "cicolors.h"
-#include "pluginvclient.h"
-
-enum
-{
-  HISTOGRAM_LINEAR,
-  HISTOGRAM_POLYNOMINAL,
-  HISTOGRAM_BEZIER,
-};
-
-
-class HistogramMain : public PluginVClient
-{
-public:
-       HistogramMain(PluginServer *server);
-       ~HistogramMain();
-
-       int process_realtime(VFrame *input_ptr, VFrame *output_ptr);
-       int is_realtime();
-       int load_defaults();
-       int save_defaults();
-       void save_data(KeyFrame *keyframe);
-       void read_data(KeyFrame *keyframe);
-       void update_gui();
-       void render_gui(void *data);
-
-       PLUGIN_CLASS_MEMBERS(HistogramConfig, HistogramThread)
-
-// Convert input to linear output
-       float calculate_linear(float input, int mode, int do_value);
-       float calculate_smooth(float input, int subscript);
-// Convert input to smoothed output by looking up in smooth table.
-       float calculate_curve(float input);
-// Calculate automatic settings
-       void calculate_automatic(VFrame *data);
-// Calculate histogram
-       void calculate_histogram(VFrame *data);
-// Calculate the linear, smoothed, lookup curves
-       void tabulate_curve(int subscript, int use_value);
-
-
-
-       YUV yuv;
-       VFrame *input, *output;
-       HistogramEngine *engine;
-       int *lookup[HISTOGRAM_MODES];
-       float *smoothed[HISTOGRAM_MODES];
-       float *linear[HISTOGRAM_MODES];
-       int *accum[HISTOGRAM_MODES];
-// Input point being dragged or edited
-       int current_point;
-// Current channel being viewed
-       int mode;
-       int dragging_point;
-       int point_x_offset;
-       int point_y_offset;
-};
-
-class HistogramPackage : public LoadPackage
-{
-public:
-       HistogramPackage();
-       int start, end;
-};
-
-class HistogramUnit : public LoadClient
-{
-public:
-       HistogramUnit(HistogramEngine *server, HistogramMain *plugin);
-       ~HistogramUnit();
-       void process_package(LoadPackage *package);
-       HistogramEngine *server;
-       HistogramMain *plugin;
-       int *accum[5];
-};
-
-class HistogramEngine : public LoadServer
-{
-public:
-       HistogramEngine(HistogramMain *plugin, 
-               int total_clients, 
-               int total_packages);
-       void process_packages(int operation, VFrame *data);
-       void init_packages();
-       LoadClient* new_client();
-       LoadPackage* new_package();
-       HistogramMain *plugin;
-       int total_size;
-
-
-       int operation;
-       enum
-       {
-               HISTOGRAM,
-               APPLY
-       };
-       VFrame *data;
-};
-
-
-
-
-
-
-
-
-
-
-
-#endif
diff --git a/cinelerra-5.0/plugins/histogram_bezier/histogram.inc b/cinelerra-5.0/plugins/histogram_bezier/histogram.inc
deleted file mode 100644 (file)
index bfbd7e3..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
- */
-
-#ifndef HISTOGRAM_INC
-#define HISTOGRAM_INC
-
-
-
-
-
-// modes
-#define HISTOGRAM_MODES 4
-#define HISTOGRAM_RED 0
-#define HISTOGRAM_GREEN 1
-#define HISTOGRAM_BLUE 2
-#define HISTOGRAM_VALUE 3
-
-// Number of divisions in histogram.  
-// 65536 + min and max range to speed up the tabulation
-#define HISTOGRAM_SLOTS 0x13333
-#define FLOAT_RANGE 1.2
-// Minimum value in percentage
-#define HISTOGRAM_MIN -10
-#define HIST_MIN_INPUT -0.1
-// Maximum value in percentage
-#define HISTOGRAM_MAX 110
-#define HIST_MAX_INPUT 1.1
-
-#define PRECISION 0.001
-#define DIGITS 3
-#define THRESHOLD_SCALE 1000
-
-#define BOX_SIZE 10
-
-
-class HistogramEngine;
-class HistogramMain;
-
-
-#endif
diff --git a/cinelerra-5.0/plugins/histogram_bezier/histogramconfig.C b/cinelerra-5.0/plugins/histogram_bezier/histogramconfig.C
deleted file mode 100644 (file)
index a3cdcf8..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
- */
-
-#include "clip.h"
-#include "histogramconfig.h"
-#include "units.h"
-
-#include <math.h>
-
-
-
-
-HistogramPoint::HistogramPoint()
- : ListItem<HistogramPoint>()
-{
-}
-
-HistogramPoint::~HistogramPoint()
-{
-}
-
-int HistogramPoint::equivalent(HistogramPoint *src)
-{
-       return EQUIV(x, src->x) && EQUIV(y, src->y) && EQUIV(gradient, src->gradient);
-}
-
-
-
-
-HistogramPoints::HistogramPoints()
- : List<HistogramPoint>()
-{
-       insert(0.0,0.0);
-       first->gradient = 1.0;
-       first->xoffset_left = 0.0;
-       first->xoffset_right = 0.05;
-       insert(1.0,1.0);
-       last->gradient = 1.0;  
-       last->xoffset_left = -0.05;
-       last->xoffset_right = 0.0;
-       
-}
-
-HistogramPoints::~HistogramPoints()
-{
-}
-
-HistogramPoint* HistogramPoints::insert(float x, float y)
-{
-       HistogramPoint *current = first;
-
-// Get existing point after new point
-       while(current)
-       {
-               if(current->x > x)
-                       break;
-               else
-                       current = NEXT;
-       }
-
-// Insert new point before current point
-       HistogramPoint *new_point = new HistogramPoint;
-       if(current)
-       {
-               insert_before(current, new_point);
-       }
-       else
-// Append new point to list
-       {
-               append(new_point);
-       }
-
-       new_point->x = x;
-       new_point->y = y;
-       new_point->xoffset_left = -0.05;
-       new_point->xoffset_right = 0.05;
-
-
-       return new_point;
-}
-
-void HistogramPoints::boundaries()
-{
-       HistogramPoint *current = first;
-       while(current)
-       {
-               CLAMP(current->x, 0.0, 1.0);
-               CLAMP(current->y, 0.0, 1.0);
-               current = NEXT;
-       }
-}
-
-int HistogramPoints::equivalent(HistogramPoints *src)
-{
-       HistogramPoint *current_this = first;
-       HistogramPoint *current_src = src->first;
-       while(current_this && current_src)
-       {
-               if(!current_this->equivalent(current_src)) return 0;
-               current_this = current_this->next;
-               current_src = current_src->next;
-       }
-
-       if(!current_this && current_src ||
-               current_this && !current_src)
-               return 0;
-       return 1;
-}
-
-void HistogramPoints::copy_from(HistogramPoints *src)
-{
-       while(last)
-               delete last;
-       HistogramPoint *current = src->first;
-       while(current)
-       {
-               HistogramPoint *new_point = new HistogramPoint;
-               new_point->x = current->x;
-               new_point->y = current->y;
-               append(new_point);
-               current = NEXT;
-       }
-}
-
-void HistogramPoints::interpolate(HistogramPoints *prev, 
-       HistogramPoints *next,
-       double prev_scale,
-       double next_scale)
-{
-       HistogramPoint *current = first;
-       HistogramPoint *current_prev = prev->first;
-       HistogramPoint *current_next = next->first;
-
-       while(current && current_prev && current_next)
-       {
-               current->x = current_prev->x * prev_scale +
-                       current_next->x * next_scale;
-               current->y = current_prev->y * prev_scale +
-                       current_next->y * next_scale;
-               current = NEXT;
-               current_prev = current_prev->next;
-               current_next = current_next->next;
-       }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-HistogramConfig::HistogramConfig()
-{
-       reset(1);
-}
-
-void HistogramConfig::reset(int do_mode)
-{
-       reset_points();
-
-       
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
-               output_min[i] = 0.0;
-               output_max[i] = 1.0;
-       }
-
-       if(do_mode) 
-       {
-               automatic = 0;
-               threshold = 0.1;
-               split = 0;
-               smoothMode = 0;
-       }
-}
-
-void HistogramConfig::reset_points()
-{
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
-               while(points[i].last) delete points[i].last;
-               points[i].insert(0.0,0.0);
-               points[i].last->gradient = 1.0;
-               points[i].insert(1.0,1.0);
-               points[i].last->gradient = 1.0;
-       }
-}
-
-
-void HistogramConfig::boundaries()
-{
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
-               points[i].boundaries();
-               CLAMP(output_min[i], HIST_MIN_INPUT, HIST_MAX_INPUT);
-               CLAMP(output_max[i], HIST_MIN_INPUT, HIST_MAX_INPUT);
-               output_min[i] = Units::quantize(output_min[i], PRECISION);
-               output_max[i] = Units::quantize(output_max[i], PRECISION);
-       }
-       CLAMP(threshold, 0, 1);
-}
-
-int HistogramConfig::equivalent(HistogramConfig &that)
-{
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
-               if(!points[i].equivalent(&that.points[i]) ||
-                       !EQUIV(output_min[i], that.output_min[i]) ||
-                       !EQUIV(output_max[i], that.output_max[i])) return 0;
-       }
-
-       if(automatic != that.automatic ||
-               !EQUIV(threshold, that.threshold)) return 0;
-
-       return 1;
-}
-
-void HistogramConfig::copy_from(HistogramConfig &that)
-{
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
-               points[i].copy_from(&that.points[i]);
-               output_min[i] = that.output_min[i];
-               output_max[i] = that.output_max[i];
-       }
-
-       automatic = that.automatic;
-       threshold = that.threshold;
-       split = that.split;
-       smoothMode = that.smoothMode;
-}
-
-void HistogramConfig::interpolate(HistogramConfig &prev, 
-       HistogramConfig &next, 
-       int64_t prev_frame, 
-       int64_t next_frame, 
-       int64_t current_frame)
-{
-       double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
-       double prev_scale = 1.0 - next_scale;
-
-       for(int i = 0; i < HISTOGRAM_MODES; i++)
-       {
-               points[i].interpolate(&prev.points[i], &next.points[i], next_scale, prev_scale);
-               output_min[i] = prev.output_min[i] * prev_scale + next.output_min[i] * next_scale;
-               output_max[i] = prev.output_max[i] * prev_scale + next.output_max[i] * next_scale;
-       }
-
-       threshold = prev.threshold * prev_scale + next.threshold * next_scale;
-       automatic = prev.automatic;
-       split = prev.split;
-       smoothMode = prev.smoothMode;
-}
-
-
-void HistogramConfig::dump()
-{
-       for(int j = 0; j < HISTOGRAM_MODES; j++)
-       {
-               printf("HistogramConfig::dump mode=%d\n", j);
-               HistogramPoints *points = &this->points[j];
-               HistogramPoint *current = points->first;
-               while(current)
-               {
-                       printf("%f,%f ", current->x, current->y);
-                       fflush(stdout);
-                       current = NEXT;
-               }
-               printf("\n");
-       }
-}
-
-
-
diff --git a/cinelerra-5.0/plugins/histogram_bezier/histogramconfig.h b/cinelerra-5.0/plugins/histogram_bezier/histogramconfig.h
deleted file mode 100644 (file)
index 4d4c664..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
- */
-
-#ifndef HISTOGRAMCONFIG_H
-#define HISTOGRAMCONFIG_H
-
-
-#include "histogram.inc"
-#include "histogramconfig.inc"
-#include "linklist.h"
-#include <stdint.h>
-
-class HistogramPoint : public ListItem<HistogramPoint>
-{
-public:
-       HistogramPoint();
-       ~HistogramPoint();
-
-       int equivalent(HistogramPoint *src);
-       float x, y;
-       float gradient;
-       float xoffset_left;
-       float xoffset_right;
-};
-
-
-class HistogramPoints : public List<HistogramPoint>
-{
-public:
-       HistogramPoints();
-       ~HistogramPoints();
-
-// Insert new point
-       HistogramPoint* insert(float x, float y);
-       int equivalent(HistogramPoints *src);
-       void boundaries();
-       void copy_from(HistogramPoints *src);
-       void interpolate(HistogramPoints *prev, 
-               HistogramPoints *next,
-               double prev_scale,
-               double next_scale);
-};
-
-class HistogramConfig
-{
-public:
-       HistogramConfig();
-
-       int equivalent(HistogramConfig &that);
-       void copy_from(HistogramConfig &that);
-       void interpolate(HistogramConfig &prev, 
-               HistogramConfig &next, 
-               int64_t prev_frame, 
-               int64_t next_frame, 
-               int64_t current_frame);
-// Used by constructor and reset button
-       void reset(int do_mode);
-       void reset_points();
-       void boundaries();
-       void dump();
-
-// Range 0 - 1.0
-// Input points
-       HistogramPoints points[HISTOGRAM_MODES];
-// Output points
-       float output_min[HISTOGRAM_MODES];
-       float output_max[HISTOGRAM_MODES];
-       int automatic;
-       float threshold;
-       int split;
-       int smoothMode;
-};
-
-
-#endif
-
-
-
diff --git a/cinelerra-5.0/plugins/histogram_bezier/histogramconfig.inc b/cinelerra-5.0/plugins/histogram_bezier/histogramconfig.inc
deleted file mode 100644 (file)
index de38650..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
- */
-
-#ifndef HISTOGRAMCONFIG_INC
-#define HISTOGRAMCONFIG_INC
-
-
-class HistogramPoint;
-class HistogramPoints;
-class HistogramConfig;
-
-
-#endif
diff --git a/cinelerra-5.0/plugins/histogram_bezier/histogramwindow.C b/cinelerra-5.0/plugins/histogram_bezier/histogramwindow.C
deleted file mode 100644 (file)
index 79e6198..0000000
+++ /dev/null
@@ -1,1064 +0,0 @@
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
- */
-
-#include "bcdisplayinfo.h"
-#include "bcsignals.h"
-#include "histogram.h"
-#include "histogramconfig.h"
-#include "histogramwindow.h"
-#include "keys.h"
-#include "language.h"
-
-
-#include <unistd.h>
-#include <string.h>
-
-PLUGIN_THREAD_OBJECT(HistogramMain, HistogramThread, HistogramWindow)
-
-
-
-HistogramWindow::HistogramWindow(HistogramMain *plugin, int x, int y)
- : BC_Window(plugin->gui_string, 
-       x,
-       y,
-       440, 
-       480, 
-       440, 
-       480, 
-       0, 
-       1,
-       1)
-{
-       this->plugin = plugin; 
-}
-
-HistogramWindow::~HistogramWindow()
-{
-}
-
-static VFrame max_picon_image(max_picon_png);
-static VFrame mid_picon_image(mid_picon_png);
-static VFrame min_picon_image(min_picon_png);
-
-int HistogramWindow::create_objects()
-{
-       int x = 10, y = 10, x1 = 10;
-       BC_Title *title = 0;
-
-       max_picon = new BC_Pixmap(this, &max_picon_image);
-       mid_picon = new BC_Pixmap(this, &mid_picon_image);
-       min_picon = new BC_Pixmap(this, &min_picon_image);
-       add_subwindow(mode_v = new HistogramMode(plugin, 
-               x, 
-               y,
-               HISTOGRAM_VALUE,
-               _("Value")));
-       x += 70;
-       add_subwindow(mode_r = new HistogramMode(plugin, 
-               x, 
-               y,
-               HISTOGRAM_RED,
-               _("Red")));
-       x += 70;
-       add_subwindow(mode_g = new HistogramMode(plugin, 
-               x, 
-               y,
-               HISTOGRAM_GREEN,
-               _("Green")));
-       x += 70;
-       add_subwindow(mode_b = new HistogramMode(plugin, 
-               x, 
-               y,
-               HISTOGRAM_BLUE,
-               _("Blue")));
-//     x += 70;
-//     add_subwindow(mode_a = new HistogramMode(plugin, 
-//             x, 
-//             y,
-//             HISTOGRAM_ALPHA,
-//             _("Alpha")));
-
-       x = x1;
-       y += 30;
-       add_subwindow(title = new BC_Title(x, y, _("Input X:")));
-       x += title->get_w() + 10;
-       input_x = new HistogramInputText(plugin,
-               this,
-               x,
-               y,
-               1);
-       input_x->create_objects();
-
-       x += input_x->get_w() + 10;
-       add_subwindow(title = new BC_Title(x, y, _("Input Y:")));
-       x += title->get_w() + 10;
-       input_y = new HistogramInputText(plugin,
-               this,
-               x,
-               y,
-               0);
-       input_y->create_objects();
-
-       y += 30;
-       x = x1;
-
-       canvas_w = get_w() - x - x;
-       canvas_h = get_h() - y - 170;
-       title1_x = x;
-       title2_x = x + (int)(canvas_w * -HIST_MIN_INPUT / FLOAT_RANGE);
-       title3_x = x + (int)(canvas_w * (1.0 - HIST_MIN_INPUT) / FLOAT_RANGE);
-       title4_x = x + (int)(canvas_w);
-       add_subwindow(canvas = new HistogramCanvas(plugin,
-               this,
-               x, 
-               y, 
-               canvas_w, 
-               canvas_h));
-       draw_canvas_overlay();
-       canvas->flash();
-
-       y += canvas->get_h() + 1;
-       add_subwindow(new BC_Title(title1_x, 
-               y, 
-               "-10%"));
-       add_subwindow(new BC_Title(title2_x,
-               y,
-               "0%"));
-       add_subwindow(new BC_Title(title3_x - get_text_width(MEDIUMFONT, "100"),
-               y,
-               "100%"));
-       add_subwindow(new BC_Title(title4_x - get_text_width(MEDIUMFONT, "110"),
-               y,
-               "110%"));
-
-       y += 20;
-       add_subwindow(title = new BC_Title(x, y, _("Output min:")));
-       x += title->get_w() + 10;
-       output_min = new HistogramOutputText(plugin,
-               this,
-               x,
-               y,
-               &plugin->config.output_min[plugin->mode]);
-       output_min->create_objects();
-       x += output_min->get_w() + 10;
-       add_subwindow(new BC_Title(x, y, _("Output Max:")));
-       x += title->get_w() + 10;
-       output_max = new HistogramOutputText(plugin,
-               this,
-               x,
-               y,
-               &plugin->config.output_max[plugin->mode]);
-       output_max->create_objects();
-
-       x = x1;
-       y += 30;
-
-       add_subwindow(output = new HistogramSlider(plugin, 
-               this,
-               x, 
-               y, 
-               get_w() - 20,
-               30,
-               0));
-       output->update();
-       y += 40;
-
-
-       add_subwindow(automatic = new HistogramAuto(plugin, 
-               x, 
-               y));
-
-       x += 120;
-       add_subwindow(new HistogramReset(plugin, 
-               x, 
-               y));
-       x += 100;
-       add_subwindow(new BC_Title(x, y, _("Threshold:")));
-       x += 100;
-       threshold = new HistogramOutputText(plugin,
-               this,
-               x,
-               y,
-               &plugin->config.threshold);
-       threshold->create_objects();
-       x = x1;
-       y += 40;        
-       add_subwindow(split = new HistogramSplit(plugin, x, y));
-       y += 6;
-       x += 150;
-       add_subwindow(new BC_Title(x,y, _("Interpolation:")));
-       x += 120;
-       add_subwindow(smoothModeChoser = new HistogramSmoothMode(plugin, this, x, y));
-       smoothModeChoser->create_objects();
-
-       show_window();
-
-       return 0;
-}
-
-WINDOW_CLOSE_EVENT(HistogramWindow)
-
-int HistogramWindow::keypress_event()
-{
-       int result = 0;
-       if(get_keypress() == BACKSPACE ||
-               get_keypress() == DELETE)
-       {
-               if(plugin->current_point >= 0)
-               {
-                       HistogramPoint *current = 
-                               plugin->config.points[plugin->mode].get_item_number(plugin->current_point);
-                       delete current;
-                       plugin->current_point = -1;
-                       update_input();
-                       update_canvas();
-                       plugin->send_configure_change();
-                       result = 1;
-               }
-       }
-       return result;
-}
-
-void HistogramWindow::update(int do_input)
-{
-       automatic->update(plugin->config.automatic);
-       threshold->update(plugin->config.threshold);
-       update_mode();
-
-       if(do_input) update_input();
-       update_output();
-}
-
-void HistogramWindow::update_input()
-{
-       input_x->update();
-       input_y->update();
-}
-
-void HistogramWindow::update_output()
-{
-       output->update();
-       output_min->update(plugin->config.output_min[plugin->mode]);
-       output_max->update(plugin->config.output_max[plugin->mode]);
-}
-
-void HistogramWindow::update_mode()
-{
-       mode_v->update(plugin->mode == HISTOGRAM_VALUE ? 1 : 0);
-       mode_r->update(plugin->mode == HISTOGRAM_RED ? 1 : 0);
-       mode_g->update(plugin->mode == HISTOGRAM_GREEN ? 1 : 0);
-       mode_b->update(plugin->mode == HISTOGRAM_BLUE ? 1 : 0);
-       output_min->output = &plugin->config.output_min[plugin->mode];
-       output_max->output = &plugin->config.output_max[plugin->mode];
-}
-
-void HistogramWindow::draw_canvas_overlay()
-{
-       canvas->set_color(0x00ff00);
-       int y1;
-
-// Calculate output curve
-       plugin->tabulate_curve(plugin->mode, 0);
-
-// Draw output line
-       for(int i = 0; i < canvas_w; i++)
-       {
-               float input = (float)i / 
-                               canvas_w * 
-                               FLOAT_RANGE + 
-                               HIST_MIN_INPUT;
-               float output = plugin->calculate_smooth(input, plugin->mode);
-
-               int y2 = canvas_h - (int)(output * canvas_h);
-               if(i > 0)
-               {
-                       canvas->draw_line(i - 1, y1, i, y2);
-               }
-               y1 = y2;
-       }
-
-// Draw output points
-       HistogramPoint *current = plugin->config.points[plugin->mode].first;
-       int number = 0;
-       while(current)
-       {
-               int x = (int)((current->x - HIST_MIN_INPUT) * canvas_w / FLOAT_RANGE);
-               int y = (int)(canvas_h - current->y * canvas_h);
-               if(number == plugin->current_point)
-                       canvas->draw_box(x - BOX_SIZE / 2, y - BOX_SIZE / 2, BOX_SIZE, BOX_SIZE);
-               else
-                       canvas->draw_rectangle(x - BOX_SIZE / 2, y - BOX_SIZE / 2, BOX_SIZE, BOX_SIZE);
-                       
-//Draw gradients
-       if (plugin->config.smoothMode > HISTOGRAM_LINEAR)
-       {       
-               int x1,x2,y1,y2;
-               canvas->set_color(0x0000ff);
-               x2 = (int)((current->x + current->xoffset_right - HIST_MIN_INPUT) * canvas_w / FLOAT_RANGE);
-               x1 = (int)((current->x + current->xoffset_left - HIST_MIN_INPUT) * canvas_w / FLOAT_RANGE);
-               y2 = (int)(canvas_h - (current->y + current->xoffset_right * current->gradient) * canvas_h);
-               y1 = (int)(canvas_h - (current->y + current->xoffset_left * current->gradient) * canvas_h);
-/*             x2 = x + (title3_x - title2_x)/20;
-               x1 = x - (title3_x - title2_x)/20;
-               y1 = y + (int)(current->gradient * (float)(canvas_h)/20.0);
-               y2 = y - (int)(current->gradient * (float)(canvas_h)/20.0);
-//             int y2 = (int)(canvas_h - canvas_h * (current->y + current->gradient /10));*/
-               canvas->draw_line(x1,y1,x2,y2);
-               
-               canvas->draw_circle(x1 - BOX_SIZE / 4, y1 - BOX_SIZE / 4, BOX_SIZE/2, BOX_SIZE/2);
-               canvas->draw_circle(x2 - BOX_SIZE / 4, y2 - BOX_SIZE / 4, BOX_SIZE/2, BOX_SIZE/2);
-               canvas->set_color(0x00ff00);
-       }
-                               
-               current = NEXT;
-               number++;
-       }
-
-
-// Draw 0 and 100% lines.
-       canvas->set_color(0xff0000);
-       canvas->draw_line(title2_x - canvas->get_x(),
-               0, 
-               title2_x - canvas->get_x(), 
-               canvas_h);
-       canvas->draw_line(title3_x - canvas->get_x(), 
-               0, 
-               title3_x - canvas->get_x(), 
-               canvas_h);
-}
-
-void HistogramWindow::update_canvas()
-{
-       int *accum = plugin->accum[plugin->mode];
-       int accum_per_canvas_i = HISTOGRAM_SLOTS / canvas_w + 1;
-       float accum_per_canvas_f = (float)HISTOGRAM_SLOTS / canvas_w;
-       int normalize = 0;
-       int max = 0;
-
-       for(int i = 0; i < HISTOGRAM_SLOTS; i++)
-       {
-               if(accum && accum[i] > normalize) normalize = accum[i];
-       }
-
-
-       if(normalize)
-       {
-               for(int i = 0; i < canvas_w; i++)
-               {
-                       int accum_start = (int)(accum_per_canvas_f * i);
-                       int accum_end = accum_start + accum_per_canvas_i;
-                       max = 0;
-                       for(int j = accum_start; j < accum_end; j++)
-                       {
-                               max = MAX(accum[j], max);
-                       }
-
-//                     max = max * canvas_h / normalize;
-                       max = (int)(log(max) / log(normalize) * canvas_h);
-
-                       canvas->set_color(0xffffff);
-                       canvas->draw_line(i, 0, i, canvas_h - max);
-                       canvas->set_color(0x000000);
-                       canvas->draw_line(i, canvas_h - max, i, canvas_h);
-               }
-       }
-       else
-       {
-               canvas->set_color(0xffffff);
-               canvas->draw_box(0, 0, canvas_w, canvas_h);
-       }
-
-
-       draw_canvas_overlay();
-       canvas->flash();
-}
-
-
-
-
-
-
-
-
-HistogramCanvas::HistogramCanvas(HistogramMain *plugin,
-       HistogramWindow *gui,
-       int x,
-       int y,
-       int w,
-       int h)
- : BC_SubWindow(x,
-       y,
-       w,
-       h,
-       0xffffff)
-{
-       this->plugin = plugin;
-       this->gui = gui;
-}
-
-int HistogramCanvas::button_press_event()
-{
-       int result = 0;
-       if(is_event_win() && cursor_inside())
-       {
-               if(!plugin->dragging_point)
-               {
-                       HistogramPoint *new_point = 0;
-                       gui->deactivate();
-// Search for existing point under cursor
-                       HistogramPoint *current = plugin->config.points[plugin->mode].first;
-                       plugin->current_point = -1;
-                       int dragID = 0;
-                       while(current)
-                       {
-                               int x = (int)((current->x - HIST_MIN_INPUT) * gui->canvas_w / FLOAT_RANGE);
-                               int y = (int)(gui->canvas_h - current->y * gui->canvas_h);
-
-/* Check for click on main point */
-                               if(get_cursor_x() >= x - BOX_SIZE / 2 &&
-                                       get_cursor_y() >= y - BOX_SIZE / 2 &&
-                                       get_cursor_x() < x + BOX_SIZE / 2 &&
-                                       get_cursor_y() < y + BOX_SIZE / 2)
-                               {
-                                       plugin->current_point = 
-                                               plugin->config.points[plugin->mode].number_of(current);
-                                       plugin->point_x_offset = get_cursor_x() - x;
-                                       plugin->point_y_offset = get_cursor_y() - y;
-                                       dragID = 1;
-                                       break;
-                               }
-                               if (plugin->config.smoothMode == HISTOGRAM_LINEAR)
-                                 break;
-
-                               int xright = 
-                                 (int)((current->x + current->xoffset_right - HIST_MIN_INPUT) * gui->canvas_w / FLOAT_RANGE);
-                               int yright = 
-                                 (int)(gui->canvas_h - (current->y + current->xoffset_right * current->gradient) * 
-                                 gui->canvas_h);
-
-/* Check for click on right handle */                          
-                               if(get_cursor_x() >= xright - BOX_SIZE / 2 &&
-                                  get_cursor_y() >= yright - BOX_SIZE / 2 &&
-                                  get_cursor_x() <  xright + BOX_SIZE / 2 &&
-                                  get_cursor_y() <  yright + BOX_SIZE / 2)
-                               {
-                                       plugin->current_point =
-                                               plugin->config.points[plugin->mode].number_of(current);
-                                       plugin->point_x_offset = get_cursor_x() - xright;
-                                       plugin->point_y_offset = get_cursor_y() - yright;
-                                       dragID = 2;
-                                       break;
-                               }
-                               
-/* Check for click on left handle */
-                               int xleft = 
-                                 (int)((current->x + current->xoffset_left - HIST_MIN_INPUT) * gui->canvas_w / FLOAT_RANGE);
-                               int yleft = 
-                                 (int)(gui->canvas_h - (current->y + current->xoffset_left * current->gradient) * 
-                                 gui->canvas_h);
-                               if(get_cursor_x() >= xleft - BOX_SIZE / 2 &&
-                                  get_cursor_y() >= yleft - BOX_SIZE / 2 &&
-                                  get_cursor_x() <  xleft + BOX_SIZE / 2 &&
-                                  get_cursor_y() <  yleft + BOX_SIZE / 2)
-                               {
-                                       plugin->current_point =
-                                               plugin->config.points[plugin->mode].number_of(current);
-                                       plugin->point_x_offset = get_cursor_x() - xleft;
-                                       plugin->point_y_offset = get_cursor_y() - yleft;
-                                       dragID = 3;
-                                       break;
-                               }
-
-
-                               current = NEXT;
-                       }
-
-                       if(plugin->current_point < 0)
-                       {
-// Create new point under cursor
-                               float current_x = (float)get_cursor_x() * 
-                                       FLOAT_RANGE / 
-                                       get_w() + 
-                                       HIST_MIN_INPUT;
-                               float current_y = 1.0 - 
-                                       (float)get_cursor_y() / 
-                                       get_h();
-                               new_point = 
-                                       plugin->config.points[plugin->mode].insert(current_x, current_y);
-                               plugin->current_point = 
-                                       plugin->config.points[plugin->mode].number_of(new_point);
-                               plugin->point_x_offset = 0;
-                               plugin->point_y_offset = 0;
-                               
-// Default gradient            
-// Get 2 points surrounding current position
-                               float x1,x2,y1,y2;
-
-                               HistogramPoint *current = plugin->config.points[plugin->mode].first;
-                               int done = 0;
-                               while(current && !done)
-                               {
-                                       if(current->x > current_x)
-                                       {
-                                               x2 = current->x;
-                                               y2 = current->y;
-                                               done = 1;
-                                       }
-                                       else
-                                               current = NEXT;
-                               }
-               
-                               current = plugin->config.points[plugin->mode].last;
-                               done = 0;
-                               while(current && !done)
-                               {
-                                       if(current->x <= current_x)
-                                       {
-                                               x1 = current->x;
-                                               y1 = current->y;
-                                               done = 1;
-                                       }
-                                       else
-                                               current = PREVIOUS;
-                               }
-                               new_point->gradient = (y2 - y1) / (x2 - x1);
-                               dragID = 1;
-                                               
-                       }
-                       
-
-                       plugin->dragging_point = dragID;
-                       result = 1;
-
-                       plugin->config.boundaries();
-                       gui->update_input();
-                       gui->update_canvas();
-                       if(new_point)
-                       {
-                               plugin->send_configure_change();
-                       }
-               }
-       }
-       return result;
-}
-
-int HistogramCanvas::cursor_motion_event()
-{
-       if(plugin->dragging_point)
-       {
-               HistogramPoint * current_point = plugin->config.points[plugin->mode].get_item_number(plugin->current_point);
-
-               float current_x = 
-                       (float)(get_cursor_x() - plugin->point_x_offset) * 
-                       FLOAT_RANGE / 
-                       get_w() + 
-                       HIST_MIN_INPUT;
-               float current_y = 1.0 - 
-                       (float)(get_cursor_y() - plugin->point_y_offset) / 
-                       get_h();
-
-               switch(plugin->dragging_point)
-               {
-                 case 1: /* Main point dragged */  
-                       current_point->x = current_x;
-                       current_point->y = current_y;
-                       break;
-                 case 2: /* Right control point dragged */
-                       if (current_x - current_point->x > 0)
-                       {
-                         current_point->xoffset_right = current_x - current_point->x;
-                         current_point->gradient = (current_y - current_point->y) / (current_x - current_point->x);
-                       }
-                       break;
-                 case 3: /* Left control point dragged */
-                       if (current_x - current_point->x < 0)
-                       {
-                         current_point->xoffset_left = current_x - current_point->x;
-                         current_point->gradient = (current_point->y - current_y) / (current_point->x - current_x);
-                       }
-                       break;
-               }
-                 
-               plugin->config.boundaries();
-               gui->update_input();
-               gui->update_canvas();
-               plugin->send_configure_change();
-               return 1;
-       }
-       return 0;
-}
-
-int HistogramCanvas::button_release_event()
-{
-       if(plugin->dragging_point)
-       {
-// Test for out of order points to delete.
-               HistogramPoint *current = 
-                       plugin->config.points[plugin->mode].get_item_number(plugin->current_point);
-               HistogramPoint *prev = PREVIOUS;
-               HistogramPoint *next = NEXT;
-
-               if((prev && prev->x >= current->x) ||
-                       (next && next->x <= current->x))
-               {
-                       delete current;
-                       plugin->current_point = -1;
-                       plugin->config.boundaries();
-                       gui->update_input();
-                       gui->update_canvas();
-                       plugin->send_configure_change();
-               }
-
-               plugin->dragging_point = 0;
-       }
-       return 0;
-}
-
-
-
-
-
-
-
-HistogramReset::HistogramReset(HistogramMain *plugin, 
-       int x,
-       int y)
- : BC_GenericButton(x, y, _("Reset"))
-{
-       this->plugin = plugin;
-}
-int HistogramReset::handle_event()
-{
-       plugin->config.reset(0);
-       plugin->thread->window->update(1);
-       plugin->thread->window->update_canvas();
-       plugin->send_configure_change();
-       return 1;
-}
-
-
-
-
-
-
-
-
-
-HistogramSlider::HistogramSlider(HistogramMain *plugin, 
-       HistogramWindow *gui,
-       int x, 
-       int y, 
-       int w,
-       int h,
-       int is_input)
- : BC_SubWindow(x, y, w, h)
-{
-       this->plugin = plugin;
-       this->gui = gui;
-       this->is_input = is_input;
-       operation = NONE;
-}
-
-int HistogramSlider::input_to_pixel(float input)
-{
-       return (int)((input - HIST_MIN_INPUT) / FLOAT_RANGE * get_w());
-}
-
-int HistogramSlider::button_press_event()
-{
-       if(is_event_win() && cursor_inside())
-       {
-               int min;
-               int max;
-               int w = get_w();
-               int h = get_h();
-               int half_h = get_h() / 2;
-
-               gui->deactivate();
-
-               if(operation == NONE)
-               {
-                       int x1 = input_to_pixel(plugin->config.output_min[plugin->mode]) - 
-                               gui->mid_picon->get_w() / 2;
-                       int x2 = x1 + gui->mid_picon->get_w();
-                       if(get_cursor_x() >= x1 && get_cursor_x() < x2 &&
-                               get_cursor_y() >= half_h && get_cursor_y() < h)
-                       {
-                               operation = DRAG_MIN_OUTPUT;
-                       }
-               }
-
-               if(operation == NONE)
-               {
-                       int x1 = input_to_pixel(plugin->config.output_max[plugin->mode]) - 
-                               gui->mid_picon->get_w() / 2;
-                       int x2 = x1 + gui->mid_picon->get_w();
-                       if(get_cursor_x() >= x1 && get_cursor_x() < x2 &&
-                               get_cursor_y() >= half_h && get_cursor_y() < h)
-                       {
-                               operation = DRAG_MAX_OUTPUT;
-                       }
-               }
-               return 1;
-       }
-       return 0;
-}
-
-int HistogramSlider::button_release_event()
-{
-       if(operation != NONE)
-       {
-               operation = NONE;
-               return 1;
-       }
-       return 0;
-}
-
-int HistogramSlider::cursor_motion_event()
-{
-       if(operation != NONE)
-       {
-               float value = (float)get_cursor_x() / get_w() * FLOAT_RANGE + HIST_MIN_INPUT;
-               CLAMP(value, HIST_MIN_INPUT, HIST_MAX_INPUT);
-
-               switch(operation)
-               {
-                       case DRAG_MIN_OUTPUT:
-                               value = MIN(plugin->config.output_max[plugin->mode], value);
-                               plugin->config.output_min[plugin->mode] = value;
-                               break;
-                       case DRAG_MAX_OUTPUT:
-                               value = MAX(plugin->config.output_min[plugin->mode], value);
-                               plugin->config.output_max[plugin->mode] = value;
-                               break;
-               }
-       
-               plugin->config.boundaries();
-               gui->update_output();
-
-               plugin->send_configure_change();
-               return 1;
-       }
-       return 0;
-}
-
-void HistogramSlider::update()
-{
-       int w = get_w();
-       int h = get_h();
-       int half_h = get_h() / 2;
-       int quarter_h = get_h() / 4;
-       int mode = plugin->mode;
-       int r = 0xff;
-       int g = 0xff;
-       int b = 0xff;
-
-       clear_box(0, 0, w, h);
-
-       switch(mode)
-       {
-               case HISTOGRAM_RED:
-                       g = b = 0x00;
-                       break;
-               case HISTOGRAM_GREEN:
-                       r = b = 0x00;
-                       break;
-               case HISTOGRAM_BLUE:
-                       r = g = 0x00;
-                       break;
-       }
-
-       for(int i = 0; i < w; i++)
-       {
-               int color = (int)(i * 0xff / w);
-               set_color(((r * color / 0xff) << 16) | 
-                       ((g * color / 0xff) << 8) | 
-                       (b * color / 0xff));
-
-               draw_line(i, 0, i, half_h);
-       }
-
-       float min;
-       float max;
-       min = plugin->config.output_min[plugin->mode];
-       max = plugin->config.output_max[plugin->mode];
-
-       draw_pixmap(gui->min_picon,
-               input_to_pixel(min) - gui->min_picon->get_w() / 2,
-               half_h + 1);
-       draw_pixmap(gui->max_picon,
-               input_to_pixel(max) - gui->max_picon->get_w() / 2,
-               half_h + 1);
-
-       flash();
-       flush();
-}
-
-
-
-
-
-
-
-
-
-HistogramAuto::HistogramAuto(HistogramMain *plugin, 
-       int x, 
-       int y)
- : BC_CheckBox(x, y, plugin->config.automatic, _("Automatic"))
-{
-       this->plugin = plugin;
-}
-
-int HistogramAuto::handle_event()
-{
-       plugin->config.automatic = get_value();
-       plugin->send_configure_change();
-       return 1;
-}
-
-
-
-
-HistogramSplit::HistogramSplit(HistogramMain *plugin, 
-       int x, 
-       int y)
- : BC_CheckBox(x, y, plugin->config.split, _("Split picture"))
-{
-       this->plugin = plugin;
-}
-
-int HistogramSplit::handle_event()
-{
-       plugin->config.split = get_value();
-       plugin->send_configure_change();
-       return 1;
-}
-
-
-
-
-HistogramMode::HistogramMode(HistogramMain *plugin, 
-       int x, 
-       int y,
-       int value,
-       char *text)
- : BC_Radial(x, y, plugin->mode == value, text)
-{
-       this->plugin = plugin;
-       this->value = value;
-}
-int HistogramMode::handle_event()
-{
-       plugin->mode = value;
-       plugin->current_point= -1;
-       plugin->thread->window->update_canvas();
-       plugin->thread->window->update_mode();
-       plugin->thread->window->update_input();
-       plugin->thread->window->update_canvas();
-       plugin->thread->window->update_output();
-       plugin->thread->window->output->update();
-//     plugin->send_configure_change();
-       return 1;
-}
-
-
-
-
-
-
-
-
-
-HistogramOutputText::HistogramOutputText(HistogramMain *plugin,
-       HistogramWindow *gui,
-       int x,
-       int y,
-       float *output)
- : BC_TumbleTextBox(gui, 
-               output ? (float)*output : 0.0,
-               (float)HIST_MIN_INPUT,
-               (float)HIST_MAX_INPUT,
-               x, 
-               y, 
-               60)
-{
-       this->plugin = plugin;
-       this->output = output;
-       set_precision(DIGITS);
-       set_increment(PRECISION);
-}
-
-
-int HistogramOutputText::handle_event()
-{
-       if(output)
-       {
-               *output = atof(get_text());
-       }
-
-       plugin->thread->window->output->update();
-       plugin->send_configure_change();
-       return 1;
-}
-
-
-
-
-
-
-
-
-HistogramInputText::HistogramInputText(HistogramMain *plugin,
-       HistogramWindow *gui,
-       int x,
-       int y,
-       int do_x)
- : BC_TumbleTextBox(gui, 
-               0.0,
-               (float)HIST_MIN_INPUT,
-               (float)HIST_MAX_INPUT,
-               x, 
-               y, 
-               60)
-{
-       this->do_x = do_x;
-       this->plugin = plugin;
-       this->gui = gui;
-       set_precision(DIGITS);
-       set_increment(PRECISION);
-}
-
-
-int HistogramInputText::handle_event()
-{
-       if(plugin->current_point >= 0 &&
-               plugin->current_point < plugin->config.points[plugin->mode].total())
-       {
-               HistogramPoint *point = 
-                       plugin->config.points[plugin->mode].get_item_number(
-                               plugin->current_point);
-
-               if(point)
-               {
-                       if(do_x) 
-                               point->x = atof(get_text());
-                       else
-                               point->y = atof(get_text());
-
-                       plugin->config.boundaries();
-                       gui->update_canvas();
-
-                       plugin->thread->window->output->update();
-                       plugin->send_configure_change();
-               }
-       }
-       return 1;
-}
-
-void HistogramInputText::update()
-{
-       if(plugin->current_point >= 0 &&
-               plugin->current_point < plugin->config.points[plugin->mode].total())
-       {
-               HistogramPoint *point = 
-
-                       plugin->config.points[plugin->mode].get_item_number(
-                               plugin->current_point);
-
-               if(point)
-               {
-                       if(do_x)
-                               BC_TumbleTextBox::update(point->x);
-                       else
-                               BC_TumbleTextBox::update(point->y);
-               }
-               else
-               {
-                       BC_TumbleTextBox::update((float)0.0);
-               }
-       }
-       else
-       {
-               BC_TumbleTextBox::update((float)0.0);
-       }
-       
-}
-
-
-HistogramSmoothMode::HistogramSmoothMode(HistogramMain*plugin, 
-       HistogramWindow *gui, 
-       int x, 
-       int y)
- : BC_PopupMenu(x, y, 120, to_text(plugin->config.smoothMode), 1)
-{
-       this->plugin = plugin;
-       this->gui = gui;
-}
-void HistogramSmoothMode::create_objects()
-{
-       add_item(new BC_MenuItem(to_text(HISTOGRAM_LINEAR)));
-       add_item(new BC_MenuItem(to_text(HISTOGRAM_POLYNOMINAL)));
-       add_item(new BC_MenuItem(to_text(HISTOGRAM_BEZIER)));
-}
-
-char* HistogramSmoothMode::to_text(int mode)
-{
-       switch(mode)
-       {
-               case HISTOGRAM_LINEAR:
-                       return _("Linear");
-               case HISTOGRAM_POLYNOMINAL:
-                       return _("Polynominal");
-               case HISTOGRAM_BEZIER:
-                       return _("Bezier");
-       }
-}
-int HistogramSmoothMode::from_text(char *text)
-{
-       if(!strcmp(text, to_text(HISTOGRAM_LINEAR))) 
-               return HISTOGRAM_LINEAR;
-       if(!strcmp(text, to_text(HISTOGRAM_POLYNOMINAL))) 
-               return HISTOGRAM_POLYNOMINAL;
-       if(!strcmp(text, to_text(HISTOGRAM_BEZIER))) 
-               return HISTOGRAM_BEZIER;
-}
-
-int HistogramSmoothMode::handle_event()
-{
-       plugin->config.smoothMode = from_text(get_text());
-       gui->update_canvas();
-       plugin->send_configure_change();
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/cinelerra-5.0/plugins/histogram_bezier/histogramwindow.h b/cinelerra-5.0/plugins/histogram_bezier/histogramwindow.h
deleted file mode 100644 (file)
index 8634d98..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
- */
-
-#ifndef HISTOGRAMWINDOW_H
-#define HISTOGRAMWINDOW_H
-
-
-
-#include "histogram.inc"
-#include "histogramwindow.inc"
-#include "pluginvclient.h"
-
-
-class HistogramSmoothMode : public BC_PopupMenu
-{
-public:
-       HistogramSmoothMode(HistogramMain *client, 
-               HistogramWindow *window, 
-               int x, 
-               int y);
-       void create_objects();
-       static char* to_text(int shape);
-       static int from_text(char *text);
-       int handle_event();
-       HistogramMain *plugin;
-       HistogramWindow *gui;
-};
-
-class HistogramSlider : public BC_SubWindow
-{
-public:
-       HistogramSlider(HistogramMain *plugin, 
-               HistogramWindow *gui,
-               int x, 
-               int y, 
-               int w,
-               int h,
-               int is_input);
-
-       void update();
-       int button_press_event();
-       int button_release_event();
-       int cursor_motion_event();
-       int input_to_pixel(float input);
-
-       int operation;
-       enum
-       {
-               NONE,
-               DRAG_INPUT,
-               DRAG_MIN_OUTPUT,
-               DRAG_MAX_OUTPUT,
-       };
-       int is_input;
-       HistogramMain *plugin;
-       HistogramWindow *gui;
-};
-
-class HistogramAuto : public BC_CheckBox
-{
-public:
-       HistogramAuto(HistogramMain *plugin, 
-               int x, 
-               int y);
-       int handle_event();
-       HistogramMain *plugin;
-};
-
-class HistogramSplit : public BC_CheckBox
-{
-public:
-       HistogramSplit(HistogramMain *plugin, 
-               int x, 
-               int y);
-       int handle_event();
-       HistogramMain *plugin;
-};
-
-class HistogramMode : public BC_Radial
-{
-public:
-       HistogramMode(HistogramMain *plugin, 
-               int x, 
-               int y,
-               int value,
-               char *text);
-       int handle_event();
-       HistogramMain *plugin;
-       int value;
-};
-
-class HistogramReset : public BC_GenericButton
-{
-public:
-       HistogramReset(HistogramMain *plugin, 
-               int x,
-               int y);
-       int handle_event();
-       HistogramMain *plugin;
-};
-
-
-class HistogramOutputText : public BC_TumbleTextBox
-{
-public:
-       HistogramOutputText(HistogramMain *plugin,
-               HistogramWindow *gui,
-               int x,
-               int y,
-               float *output);
-       int handle_event();
-       HistogramMain *plugin;
-       float *output;
-};
-
-class HistogramInputText : public BC_TumbleTextBox
-{
-public:
-       HistogramInputText(HistogramMain *plugin,
-               HistogramWindow *gui,
-               int x,
-               int y,
-               int do_x);
-
-       int handle_event();
-       void update();
-
-       HistogramMain *plugin;
-       HistogramWindow *gui;
-       int do_x;
-};
-
-class HistogramCanvas : public BC_SubWindow
-{
-public:
-       HistogramCanvas(HistogramMain *plugin,
-               HistogramWindow *gui,
-               int x,
-               int y,
-               int w,
-               int h);
-       int button_press_event();
-       int cursor_motion_event();
-       int button_release_event();
-       HistogramMain *plugin;
-       HistogramWindow *gui;
-};
-
-class HistogramWindow : public BC_Window
-{
-public:
-       HistogramWindow(HistogramMain *plugin, int x, int y);
-       ~HistogramWindow();
-
-       void create_objects();
-       int close_event();
-       void update(int do_input);
-       void update_mode();
-       void update_canvas();
-       void draw_canvas_overlay();
-       void update_input();
-       void update_output();
-       int keypress_event();
-
-       HistogramSlider *output;
-       HistogramAuto *automatic;
-       HistogramSplit *split;
-       HistogramSmoothMode *smoothModeChoser;
-       HistogramMode *mode_v, *mode_r, *mode_g, *mode_b /*,  *mode_a */;
-       HistogramOutputText *output_min;
-       HistogramOutputText *output_max;
-       HistogramOutputText *threshold;
-       HistogramInputText *input_x;
-       HistogramInputText *input_y;
-       HistogramCanvas *canvas;
-       HistogramMain *plugin;
-       int canvas_w;
-       int canvas_h;
-       int title1_x;
-       int title2_x;
-       int title3_x;
-       int title4_x;
-       BC_Pixmap *max_picon, *mid_picon, *min_picon;
-};
-
-
-
-PLUGIN_THREAD_HEADER(HistogramMain, HistogramThread, HistogramWindow)
-
-
-
-
-#endif
diff --git a/cinelerra-5.0/plugins/histogram_bezier/histogramwindow.inc b/cinelerra-5.0/plugins/histogram_bezier/histogramwindow.inc
deleted file mode 100644 (file)
index cc9e113..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
- */
-
-#ifndef HISTOGRAMWINDOW_INC
-#define HISTOGRAMWINDOW_INC
-
-class HistogramWindow;
-class HistogramThread;
-
-#endif