#include "clip.h"
#include "bchash.h"
#include "filexml.h"
-#include "histogram.h"
-#include "histogramconfig.h"
-#include "histogramwindow.h"
+#include "bistogram.h"
+#include "bistogramconfig.h"
+#include "bistogramwindow.h"
#include "keyframe.h"
#include "language.h"
#include "loadbalance.h"
class HistogramEngine;
class HistogramWindow;
-
-
-
-
REGISTER_PLUGIN(HistogramMain)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
HistogramMain::HistogramMain(PluginServer *server)
: PluginVClient(server)
{
delete engine;
}
-char* HistogramMain::plugin_title() { return _("Histogram"); }
+const char* HistogramMain::plugin_title() { return _("Histogram Bezier"); }
int HistogramMain::is_realtime() { return 1; }
-
-SHOW_GUI_MACRO(HistogramMain, HistogramThread)
-
-SET_STRING_MACRO(HistogramMain)
-
-RAISE_WINDOW_MACRO(HistogramMain)
-
+NEW_WINDOW_MACRO(HistogramMain, HistogramWindow)
LOAD_CONFIGURATION_MACRO(HistogramMain, HistogramConfig)
void HistogramMain::render_gui(void *data)
calculate_automatic((VFrame*)data);
}
- thread->window->lock_window("HistogramMain::render_gui");
- thread->window->update_canvas();
+ HistogramWindow *window = (HistogramWindow *)thread->window;
+ window->lock_window("HistogramMain::render_gui");
+ window->update_canvas();
if(config.automatic)
{
- thread->window->update_input();
+ window->update_input();
}
- thread->window->unlock_window();
+ window->unlock_window();
}
}
int reconfigure = load_configuration();
if(reconfigure)
{
- thread->window->update(0);
+ HistogramWindow *window = (HistogramWindow *)thread->window;
+ window->update(0);
if(!config.automatic)
{
- thread->window->update_input();
+ 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;
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();
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;
}
int done = 0;
float output;
- if(input < 0)
- {
+ if(input < 0) {
output = 0;
done = 1;
}
- if(input > 1)
- {
+ if(input > 1) {
output = 1;
done = 1;
}
- if(!done)
- {
+ if(!done) {
- float x1 = 0;
- float y1 = 0;
+ float x1 = 0, y1 = 0;
float grad1 = 1.0;
float x1right = 0;
- float x2 = 1;
- float y2 = 1;
+ 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)
- {
+ while(current && !done) {
+ if(current->x > input) {
x2 = current->x;
y2 = current->y;
grad2 = current->gradient;
current = points->last;
done = 0;
- while(current && !done)
- {
- if(current->x <= input)
- {
+ while(current && !done) {
+ if(current->x <= input) {
x1 = current->x;
y1 = current->y;
grad1 = current->gradient;
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;
+ 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)
{
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)
- {
+ 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);
-
-
+ output = output_min + output * (output_max - output_min);
return output;
}
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);
+ 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];
}
engine->process_packages(HistogramEngine::HISTOGRAM, data);
- for(int i = 0; i < engine->get_total_clients(); i++)
- {
+ for(int i = 0; i < engine->get_total_clients(); i++) {
HistogramUnit *unit = (HistogramUnit*)engine->get_client(i);
- if(i == 0)
- {
+ 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++)
- {
+ 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++)
// Remove top and bottom from calculations. Doesn't work in high
// precision colormodels.
- for(int i = 0; i < HISTOGRAM_MODES; i++)
- {
+ for(int i = 0; i < HISTOGRAM_MODES; i++) {
accum[i][0] = 0;
accum[i][HISTOGRAM_SLOTS - 1] = 0;
}
config.reset_points();
// Do each channel
- for(int i = 0; i < 3; i++)
- {
+ for(int i = 0; i < 3; i++) {
int *accum = this->accum[i];
int pixels = data->get_w() * data->get_h();
float white_fraction = 1.0 - (1.0 - config.threshold) / 2;
float min_level = 0.0;
// Get histogram slot above threshold of pixels
- for(int j = 0; j < HISTOGRAM_SLOTS; j++)
- {
+ for(int j = 0; j < HISTOGRAM_SLOTS; j++) {
total += accum[j];
- if(total >= threshold)
- {
+ 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--)
- {
+ for(int j = HISTOGRAM_SLOTS - 1; j >= 0; j--) {
total += accum[j];
- if(total >= threshold)
- {
+ 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,
// 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)
- {
+ if( !lookup[0] || !smoothed[0] || !linear[0] || config.automatic)
+ need_reconfigure = 1;
+ if( need_reconfigure ) {
SET_TRACE
// Calculate new curves
- if(config.automatic)
- {
+ if(config.automatic) {
calculate_automatic(input);
}
SET_TRACE
SET_TRACE
}
-
-
-
// Apply histogram
engine->process_packages(HistogramEngine::APPLY, input);
SET_TRACE
-
return 0;
}
float *current_linear = linear[subscript];
// Make linear curve
- for(i = 0; i < HISTOGRAM_SLOTS; i++)
- {
+ 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;
+ //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];
+// prev = current_smooth[i];
}
-
-
// Generate lookup tables for integer colormodels
if(input)
{
}
}
-
-
-
-
-
-
-
-
-
-
-
HistogramPackage::HistogramPackage()
: LoadPackage()
{
}
-
-
-
HistogramUnit::HistogramUnit(HistogramEngine *server,
HistogramMain *plugin)
: LoadClient(server)
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); \
+ 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]++; \
} \
}
-
-
-
VFrame *data = server->data;
int w = data->get_w();
- int h = data->get_h();
+// 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;
+ int r, g, b, y, u, v;
switch(data->get_color_model())
{
VFrame *input = plugin->input;
- VFrame *output = plugin->output;
- int w = input->get_w();
- int h = input->get_h();
+// 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, a;
+ int r, g, b, y, u, v;
switch(input->get_color_model())
{
case BC_RGB888:
void HistogramEngine::init_packages()
{
- switch(operation)
- {
+ switch(operation) {
case HISTOGRAM:
total_size = data->get_h();
break;
break;
}
-
- int package_size = (int)((float)total_size /
- get_total_packages() + 1);
- int start = 0;
-
- for(int i = 0; i < get_total_packages(); i++)
- {
+ 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++)
- {
+ 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);
#include "bcdisplayinfo.h"
#include "bcsignals.h"
-#include "histogram.h"
-#include "histogramconfig.h"
-#include "histogramwindow.h"
+#include "bistogram.h"
+#include "bistogramconfig.h"
+#include "bistogramwindow.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)
+HistogramWindow::HistogramWindow(HistogramMain *plugin)
+ : PluginClientWindow(plugin, 440, 480, 440, 480, 0)
{
- this->plugin = plugin;
+ 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);
+#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);
-int HistogramWindow::create_objects()
+void 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);
+ 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,
smoothModeChoser->create_objects();
show_window();
-
- return 0;
}
-WINDOW_CLOSE_EVENT(HistogramWindow)
-
int HistogramWindow::keypress_event()
{
int result = 0;
int HistogramReset::handle_event()
{
plugin->config.reset(0);
- plugin->thread->window->update(1);
- plugin->thread->window->update_canvas();
+ HistogramWindow *window = (HistogramWindow *)plugin->thread->window;
+ window->update(1);
+ window->update_canvas();
plugin->send_configure_change();
return 1;
}
{
if(is_event_win() && cursor_inside())
{
- int min;
- int max;
- int w = get_w();
+// int w = get_w();
int h = get_h();
int half_h = get_h() / 2;
int w = get_w();
int h = get_h();
int half_h = get_h() / 2;
- int quarter_h = get_h() / 4;
+// int quarter_h = get_h() / 4;
int mode = plugin->mode;
int r = 0xff;
int g = 0xff;
{
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();
+ 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;
}
*output = atof(get_text());
}
- plugin->thread->window->output->update();
+ HistogramWindow *window = (HistogramWindow *)plugin->thread->window;
+ window->output->update();
plugin->send_configure_change();
return 1;
}
plugin->config.boundaries();
gui->update_canvas();
- plugin->thread->window->output->update();
+ HistogramWindow *window = (HistogramWindow *)plugin->thread->window;
+ window->output->update();
plugin->send_configure_change();
}
}
case HISTOGRAM_BEZIER:
return _("Bezier");
}
+ return _("None");
}
+
int HistogramSmoothMode::from_text(char *text)
{
if(!strcmp(text, to_text(HISTOGRAM_LINEAR)))
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;
}