#include <unistd.h>
#include "bcdisplayinfo.h"
+#include "bchash.h"
+#include "bcprogressbox.h"
#include "bcsignals.h"
#include "clip.h"
-#include "bchash.h"
+#include "edl.h"
#include "filexml.h"
#include "histogram.h"
#include "histogramconfig.h"
#include "keyframe.h"
#include "language.h"
#include "loadbalance.h"
+#include "localsession.h"
+#include "mainsession.h"
+#include "mwindow.h"
#include "playback3d.h"
+#include "pluginserver.h"
#include "bccolors.h"
#include "vframe.h"
#include "workarounds.h"
class HistogramWindow;
-
-
-
REGISTER_PLUGIN(HistogramMain)
-
-
-
-
-
-
-
-
HistogramMain::HistogramMain(PluginServer *server)
: PluginVClient(server)
{
-
engine = 0;
- for(int i = 0; i < HISTOGRAM_MODES; i++)
- {
- lookup[i] = 0;
- accum[i] = 0;
- preview_lookup[i] = 0;
+ for( int i=0; i<HISTOGRAM_MODES; ++i ) {
+ lookup[i] = new int[0x10000];
+ preview_lookup[i] = new int[0x10000];
+ accum[i] = new int64_t[HISTOGRAM_SLOTS];
+ bzero(accum[i], sizeof(int64_t)*HISTOGRAM_SLOTS);
}
current_point = -1;
mode = HISTOGRAM_VALUE;
+ last_position = -1;
+ need_reconfigure = 1;
+ sum_frames = 0;
+ frames = 1;
dragging_point = 0;
input = 0;
output = 0;
HistogramMain::~HistogramMain()
{
- for(int i = 0; i < HISTOGRAM_MODES;i++)
- {
+ for( int i=0; i<HISTOGRAM_MODES; ++i ) {
delete [] lookup[i];
- delete [] accum[i];
delete [] preview_lookup[i];
+ delete [] accum[i];
}
delete engine;
}
void HistogramMain::render_gui(void *data)
{
- if(thread)
- {
-// Process just the RGB values to determine the automatic points or
-// all the points if manual
- if(!config.automatic)
- {
-// Generate curves for value histogram
-// Lock out changes to curves
- ((HistogramWindow*)thread->window)->lock_window("HistogramMain::render_gui 1");
- tabulate_curve(HISTOGRAM_RED, 0);
- tabulate_curve(HISTOGRAM_GREEN, 0);
- tabulate_curve(HISTOGRAM_BLUE, 0);
- ((HistogramWindow*)thread->window)->unlock_window();
- }
-
- calculate_histogram((VFrame*)data, !config.automatic);
-
-
- if(config.automatic)
- {
- calculate_automatic((VFrame*)data);
-
-// Generate curves for value histogram
-// Lock out changes to curves
- ((HistogramWindow*)thread->window)->lock_window("HistogramMain::render_gui 1");
- tabulate_curve(HISTOGRAM_RED, 0);
- tabulate_curve(HISTOGRAM_GREEN, 0);
- tabulate_curve(HISTOGRAM_BLUE, 0);
- ((HistogramWindow*)thread->window)->unlock_window();
-
-
-// Need a second pass to get the luminance values.
- calculate_histogram((VFrame*)data, 1);
- }
-
- ((HistogramWindow*)thread->window)->lock_window("HistogramMain::render_gui 2");
+ if( !thread ) return;
+ HistogramWindow *window = (HistogramWindow*)thread->window;
+ HistogramMain *plugin = (HistogramMain*)data;
+//update gui client instance, needed for drawing
+ for( int i=0; i<HISTOGRAM_MODES; ++i ) {
+ config.low_input[i] = plugin->config.low_input[i];
+ config.high_input[i] = plugin->config.high_input[i];
+ memcpy(accum[i], plugin->accum[i], HISTOGRAM_SLOTS*sizeof(*accum));
+ }
+ window->lock_window("HistogramMain::render_gui 2");
+// draw all if reconfigure
+ int reconfig = plugin->need_reconfigure;
// Always draw the histogram but don't update widgets if automatic
- ((HistogramWindow*)thread->window)->update(1,
- config.automatic && mode != HISTOGRAM_VALUE,
- config.automatic && mode != HISTOGRAM_VALUE,
- 0);
-
- ((HistogramWindow*)thread->window)->unlock_window();
- }
+ int auto_rgb = reconfig ? 1 : config.automatic && mode != HISTOGRAM_VALUE ? 1 : 0;
+ window->update(1, auto_rgb, auto_rgb, reconfig);
+ window->unlock_window();
}
void HistogramMain::update_gui()
{
- if(thread)
- {
+ if( thread ) {
((HistogramWindow*)thread->window)->lock_window("HistogramMain::update_gui");
int reconfigure = load_configuration();
- if(reconfigure)
- {
- ((HistogramWindow*)thread->window)->update(1,
- 1,
- 1,
- 1);
- }
+ if( reconfigure )
+ ((HistogramWindow*)thread->window)->update(1, 1, 1, 1);
((HistogramWindow*)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->xbuf);
output.tag.set_title("HISTOGRAM");
output.tag.set_property("AUTOMATIC", config.automatic);
output.tag.set_property("THRESHOLD", config.threshold);
output.tag.set_property("PLOT", config.plot);
+ output.tag.set_property("SUM_FRAMES", config.sum_frames);
output.tag.set_property("SPLIT", config.split);
+ output.tag.set_property("LOG_SLIDER", config.log_slider);
output.tag.set_property("W", w);
output.tag.set_property("H", h);
output.tag.set_property("PARADE", parade);
output.tag.set_property("MODE", mode);
- for(int i = 0; i < HISTOGRAM_MODES; i++)
- {
+ for( int i=0; i<HISTOGRAM_MODES; ++i ) {
sprintf(string, "LOW_OUTPUT_%d", i);
output.tag.set_property(string, config.low_output[i]);
sprintf(string, "HIGH_OUTPUT_%d", i);
output.tag.set_property(string, config.high_input[i]);
sprintf(string, "GAMMA_%d", i);
output.tag.set_property(string, config.gamma[i]);
-//printf("HistogramMain::save_data %d %f %d\n", config.input_min[i], config.input_mid[i], config.input_max[i]);
}
output.append_tag();
input.set_shared_input(keyframe->xbuf);
int result = 0;
+ while( !(result = input.read_tag()) ) {
+ if( input.tag.title_is("HISTOGRAM") ) {
+ config.automatic = input.tag.get_property("AUTOMATIC", config.automatic);
+ config.threshold = input.tag.get_property("THRESHOLD", config.threshold);
+ config.plot = input.tag.get_property("PLOT", config.plot);
+ config.sum_frames = input.tag.get_property("SUM_FRAMES", config.sum_frames);
+ config.split = input.tag.get_property("SPLIT", config.split);
+ config.log_slider = input.tag.get_property("LOG_SLIDER", config.log_slider);
+
+ if( is_defaults() ) {
+ w = input.tag.get_property("W", w);
+ h = input.tag.get_property("H", h);
+ parade = input.tag.get_property("PARADE", parade);
+ mode = input.tag.get_property("MODE", mode);
+ }
-
- while(!result)
- {
- result = input.read_tag();
-
- if(!result)
- {
- if(input.tag.title_is("HISTOGRAM"))
- {
- config.automatic = input.tag.get_property("AUTOMATIC", config.automatic);
- config.threshold = input.tag.get_property("THRESHOLD", config.threshold);
- config.plot = input.tag.get_property("PLOT", config.plot);
- config.split = input.tag.get_property("SPLIT", config.split);
-
- if(is_defaults())
- {
- w = input.tag.get_property("W", w);
- h = input.tag.get_property("H", h);
- parade = input.tag.get_property("PARADE", parade);
- mode = input.tag.get_property("MODE", mode);
- }
-
- char string[BCTEXTLEN];
- for(int i = 0; i < HISTOGRAM_MODES; i++)
- {
- sprintf(string, "LOW_OUTPUT_%d", i);
- config.low_output[i] = input.tag.get_property(string, config.low_output[i]);
- sprintf(string, "HIGH_OUTPUT_%d", i);
- config.high_output[i] = input.tag.get_property(string, config.high_output[i]);
- sprintf(string, "GAMMA_%d", i);
- config.gamma[i] = input.tag.get_property(string, config.gamma[i]);
-
- if(i == HISTOGRAM_VALUE || !config.automatic)
- {
- sprintf(string, "LOW_INPUT_%d", i);
- config.low_input[i] = input.tag.get_property(string, config.low_input[i]);
- sprintf(string, "HIGH_INPUT_%d", i);
- config.high_input[i] = input.tag.get_property(string, config.high_input[i]);
- }
-//printf("HistogramMain::read_data %d %f %d\n", config.input_min[i], config.input_mid[i], config.input_max[i]);
+ char string[BCTEXTLEN];
+ for( int i=0; i<HISTOGRAM_MODES; ++i ) {
+ sprintf(string, "LOW_OUTPUT_%d", i);
+ config.low_output[i] = input.tag.get_property(string, config.low_output[i]);
+ sprintf(string, "HIGH_OUTPUT_%d", i);
+ config.high_output[i] = input.tag.get_property(string, config.high_output[i]);
+ sprintf(string, "GAMMA_%d", i);
+ config.gamma[i] = input.tag.get_property(string, config.gamma[i]);
+
+ if( i == HISTOGRAM_VALUE || !config.automatic ) {
+ sprintf(string, "LOW_INPUT_%d", i);
+ config.low_input[i] = input.tag.get_property(string, config.low_input[i]);
+ sprintf(string, "HIGH_INPUT_%d", i);
+ config.high_input[i] = input.tag.get_property(string, config.high_input[i]);
}
}
}
}
config.boundaries();
-
}
-float HistogramMain::calculate_level(float input,
- int mode,
- int use_value)
+float HistogramMain::calculate_level(float input, int mode, int use_value)
{
float output = 0.0;
// Scale to input range
- if(!EQUIV(config.high_input[mode], config.low_input[mode]))
- {
+ if( !EQUIV(config.high_input[mode], config.low_input[mode]) ) {
output = input < config.low_input[mode] ? 0 :
(input - config.low_input[mode]) /
(config.high_input[mode] - config.low_input[mode]);
}
else
- {
output = input;
- }
-
-
- if(!EQUIV(config.gamma[mode], 0))
- {
+ if( !EQUIV(config.gamma[mode], 0) ) {
output = pow(output, 1.0 / config.gamma[mode]);
- CLAMP(output, 0, 1.0);
+ CLAMP(output, 0, 100.0);
}
// Apply value curve
- if(use_value && mode != HISTOGRAM_VALUE)
- {
+ if( use_value && mode != HISTOGRAM_VALUE )
output = calculate_level(output, HISTOGRAM_VALUE, 0);
- }
-
-
-
// scale to output range
- if(!EQUIV(config.low_output[mode], config.high_output[mode]))
- {
+ if( !EQUIV(config.low_output[mode], config.high_output[mode]) ) {
output = output * (config.high_output[mode] - config.low_output[mode]) +
config.low_output[mode];
}
CLAMP(output, 0, 1.0);
-
return output;
}
-
-
void HistogramMain::calculate_histogram(VFrame *data, int do_value)
{
- if( !engine )
- {
+ if( !engine ) {
int cpus = data->get_w() * data->get_h() / 0x80000 + 2;
int smps = get_project_smp();
if( cpus > smps ) cpus = smps;
engine = new HistogramEngine(this, cpus, cpus);
}
- if(!accum[0])
- {
- for(int i = 0; i < HISTOGRAM_MODES; i++)
- accum[i] = new int[HISTOGRAM_SLOTS];
- }
engine->process_packages(HistogramEngine::HISTOGRAM, data, do_value);
- for(int i = 0; i < engine->get_total_clients(); i++)
- {
- HistogramUnit *unit = (HistogramUnit*)engine->get_client(i);
+ int k = 0;
+ HistogramUnit *unit = (HistogramUnit*)engine->get_client(0);
+ if( !sum_frames ) {
+ frames = 0;
+ for( int i=0; i<HISTOGRAM_MODES; ++i )
+ memcpy(accum[i], unit->accum[i], sizeof(int64_t)*HISTOGRAM_SLOTS);
+ k = 1;
+ }
- 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];
- }
+ for( int i=k,n=engine->get_total_clients(); i<n; ++i ) {
+ unit = (HistogramUnit*)engine->get_client(i);
+ for( int j=0; j<HISTOGRAM_MODES; ++j ) {
+ int64_t *in = unit->accum[j], *out = accum[j];
+ for( int k=HISTOGRAM_SLOTS; --k>=0; ) *out++ += *in++;
}
}
// 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;
}
+ ++frames;
}
config.reset_points(1);
// Do each channel
- for(int i = 0; i < 3; i++)
- {
- int *accum = this->accum[i];
- int pixels = data->get_w() * data->get_h();
+ for( int i=0; i<3; ++i ) {
+ int64_t *accum = this->accum[i];
+ int64_t sz = data->get_w() * data->get_h();
+ int64_t pixels = sz * frames;
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;
+ float min_level = 0.0, max_level = 1.0;
// Get histogram slot above threshold of pixels
- for(int j = 0; j < HISTOGRAM_SLOTS; j++)
- {
+ int64_t total = 0;
+ 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
+// Get histogram slot below threshold of pixels
total = 0;
- for(int j = HISTOGRAM_SLOTS - 1; j >= 0; j--)
- {
+ for( int j=HISTOGRAM_SLOTS; --j> 0; ) {
total += accum[j];
- if(total >= threshold)
- {
+ if( total >= threshold ) {
min_level = (float)j / HISTOGRAM_SLOTS * FLOAT_RANGE + HIST_MIN_INPUT;
break;
}
}
-
config.low_input[i] = min_level;
config.high_input[i] = max_level;
}
}
-
-
-
int HistogramMain::calculate_use_opengl()
{
// glHistogram doesn't work.
int64_t start_position,
double frame_rate)
{
- int need_reconfigure = load_configuration();
-
-
-
+ need_reconfigure = load_configuration();
int use_opengl = calculate_use_opengl();
-
-//printf("%d\n", use_opengl);
- read_frame(frame,
- 0,
- start_position,
- frame_rate,
- use_opengl);
-
-// Apply histogram in hardware
- if(use_opengl) return run_opengl();
-
+ sum_frames = last_position == start_position ? config.sum_frames : 0;
+ last_position = get_direction() == PLAY_FORWARD ?
+ start_position+1 : start_position-1;
this->input = frame;
this->output = frame;
+ int cpus = input->get_w() * input->get_h() / 0x80000 + 2;
+ int smps = get_project_smp();
+ if( cpus > smps ) cpus = smps;
if( !engine )
- {
- int cpus = input->get_w() * input->get_h() / 0x80000 + 2;
- int smps = get_project_smp();
- if( cpus > smps ) cpus = smps;
engine = new HistogramEngine(this, cpus, cpus);
+ read_frame(frame, 0, start_position, frame_rate, use_opengl);
+ if( config.automatic )
+ calculate_automatic(frame);
+ if( config.plot ) {
+// Generate curves for value histogram
+ tabulate_curve(lookup, 0);
+ tabulate_curve(preview_lookup, 0, 0x10000);
+// Need to get the luminance values.
+ calculate_histogram(input, 1);
+ send_render_gui(this);
}
-// Always plot to set the curves if automatic
- if(config.plot || config.automatic) send_render_gui(frame);
-// 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] ||
- config.automatic)
- {
+ if( need_reconfigure || config.automatic || config.plot ) {
// Calculate new curves
- if(config.automatic)
- {
- calculate_automatic(input);
- }
-
-
// Generate transfer tables with value function for integer colormodels.
- for(int i = 0; i < 3; i++)
- tabulate_curve(i, 1);
+ tabulate_curve(lookup, 1);
}
-// printf("HistogramMain::process_buffer %d %f %f %f %f %f %f %f %f %f\n",
-// __LINE__,
-// config.low_input[HISTOGRAM_RED],
-// config.gamma[HISTOGRAM_RED],
-// config.high_input[HISTOGRAM_RED],
-// config.low_input[HISTOGRAM_GREEN],
-// config.gamma[HISTOGRAM_GREEN],
-// config.high_input[HISTOGRAM_GREEN],
-// config.low_input[HISTOGRAM_BLUE],
-// config.gamma[HISTOGRAM_BLUE],
-// config.high_input[HISTOGRAM_BLUE]);
-
-
+// Apply histogram in hardware
+ if( use_opengl )
+ return run_opengl();
// Apply histogram
engine->process_packages(HistogramEngine::APPLY, input, 0);
-
-
return 0;
}
-void HistogramMain::tabulate_curve(int subscript, int use_value)
+void HistogramMain::tabulate_curve(int **table, int idx, int use_value, int len)
{
- int i;
- if(!lookup[subscript])
- lookup[subscript] = new int[HISTOGRAM_SLOTS];
- if(!preview_lookup[subscript])
- preview_lookup[subscript] = new int[HISTOGRAM_SLOTS];
-
-//printf("HistogramMain::tabulate_curve %d input=%p\n", __LINE__, input);
-
-
-// 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_level((float)i / 0xff, subscript, use_value) *
- 0xff);
- CLAMP(lookup[subscript][i], 0, 0xff);
- }
- break;
-// All other integer colormodels are converted to 16 bit RGB
- default:
- for(i = 0; i < 0x10000; i++)
- {
- lookup[subscript][i] =
- (int)(calculate_level((float)i / 0xffff, subscript, use_value) *
- 0xffff);
- CLAMP(lookup[subscript][i], 0, 0xffff);
- }
-// for(i = 0; i < 0x100; i++)
-// {
-// if(subscript == HISTOGRAM_BLUE) printf("%d ", lookup[subscript][i * 0x100]);
-// }
-// if(subscript == HISTOGRAM_BLUE) printf("\n");
-
- break;
- }
+ int len1 = len - 1;
+ int *curve = table[idx];
+ for( int i=0; i<len; ++i ) {
+ curve[i] = calculate_level((float)i/len1, idx, use_value) * len1;
+ CLAMP(curve[i], 0, len1);
}
+}
-// Lookup table for preview only used for GUI
- if(!use_value)
- {
- for(i = 0; i < 0x10000; i++)
- {
- preview_lookup[subscript][i] =
- (int)(calculate_level((float)i / 0xffff, subscript, use_value) *
- 0xffff);
- CLAMP(preview_lookup[subscript][i], 0, 0xffff);
- }
- }
+void HistogramMain::tabulate_curve(int **table, int use_value, int len)
+{
+// uint8 rgb is 8 bit, all others are converted to 16 bit RGB
+ if( len < 0 ) {
+ int color_model = input->get_color_model();
+ len = color_model == BC_RGB888 || color_model == BC_RGBA8888 ?
+ 0x100 : 0x10000;
+ }
+ for( int i=0; i<3; ++i )
+ tabulate_curve(table, i, use_value, len);
}
int HistogramMain::handle_opengl()
}
-
-
-
-
-
-
-
-
-
-
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];
+ accum[i] = new int64_t[HISTOGRAM_SLOTS];
}
HistogramUnit::~HistogramUnit()
void HistogramUnit::process_package(LoadPackage *package)
{
HistogramPackage *pkg = (HistogramPackage*)package;
-
- if(server->operation == HistogramEngine::HISTOGRAM)
- {
+ switch( server->operation ) {
+ case HistogramEngine::HISTOGRAM: {
int do_value = server->do_value;
+ const int hmin = HISTOGRAM_MIN * 0xffff / 100;
+ const int slots1 = HISTOGRAM_SLOTS-1;
-
-#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_HEAD(type) { \
+ type **rows = (type**)data->get_rows(); \
+ for( int iy=pkg->start; iy<pkg->end; ++iy ) { \
+ type *row = rows[iy]; \
+ for( int ix=0; ix<w; ++ix ) {
#define HISTOGRAM_TAIL(components) \
-/* Value takes the maximum of the output RGB values */ \
- if(do_value) \
- { \
- CLAMP(r, 0, HISTOGRAM_SLOTS - 1); \
- CLAMP(g, 0, HISTOGRAM_SLOTS - 1); \
- CLAMP(b, 0, HISTOGRAM_SLOTS - 1); \
- r_out = lookup_r[r]; \
- g_out = lookup_g[g]; \
- b_out = lookup_b[b]; \
+ if( do_value ) { \
+ r_out = preview_r[bclip(r, 0, 0xffff)]; \
+ g_out = preview_g[bclip(g, 0, 0xffff)]; \
+ b_out = preview_b[bclip(b, 0, 0xffff)]; \
/* v = (r * 76 + g * 150 + b * 29) >> 8; */ \
- v = MAX(r_out, g_out); \
- v = MAX(v, b_out); \
- v += -HISTOGRAM_MIN * 0xffff / 100; \
- CLAMP(v, 0, HISTOGRAM_SLOTS - 1); \
- accum_v[v]++; \
+/* Value takes the maximum of the output RGB values */ \
+ int v = MAX(r_out, g_out); v = MAX(v, b_out); \
+ ++accum_v[bclip(v -= hmin, 0, slots1)]; \
} \
\
- r += -HISTOGRAM_MIN * 0xffff / 100; \
- g += -HISTOGRAM_MIN * 0xffff / 100; \
- b += -HISTOGRAM_MIN * 0xffff / 100; \
- CLAMP(r, 0, HISTOGRAM_SLOTS - 1); \
- CLAMP(g, 0, HISTOGRAM_SLOTS - 1); \
- CLAMP(b, 0, HISTOGRAM_SLOTS - 1); \
- accum_r[r]++; \
- accum_g[g]++; \
- accum_b[b]++; \
+ ++accum_r[bclip(r -= hmin, 0, slots1)]; \
+ ++accum_g[bclip(g -= hmin, 0, slots1)]; \
+ ++accum_b[bclip(b -= hmin, 0, slots1)]; \
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];
+ int64_t *accum_r = accum[HISTOGRAM_RED];
+ int64_t *accum_g = accum[HISTOGRAM_GREEN];
+ int64_t *accum_b = accum[HISTOGRAM_BLUE];
+ int64_t *accum_v = accum[HISTOGRAM_VALUE];
int32_t r, g, b, y, u, v;
int r_out, g_out, b_out;
- int *lookup_r = plugin->preview_lookup[HISTOGRAM_RED];
- int *lookup_g = plugin->preview_lookup[HISTOGRAM_GREEN];
- int *lookup_b = plugin->preview_lookup[HISTOGRAM_BLUE];
-
- switch(data->get_color_model())
- {
- case BC_RGB888:
- HISTOGRAM_HEAD(unsigned char)
- r = (row[0] << 8) | row[0];
- g = (row[1] << 8) | row[1];
- b = (row[2] << 8) | row[2];
- HISTOGRAM_TAIL(3)
- break;
- case BC_RGB_FLOAT:
- HISTOGRAM_HEAD(float)
- r = (int)(row[0] * 0xffff);
- g = (int)(row[1] * 0xffff);
- b = (int)(row[2] * 0xffff);
- HISTOGRAM_TAIL(3)
- break;
- case BC_YUV888:
- HISTOGRAM_HEAD(unsigned char)
- y = (row[0] << 8) | row[0];
- u = (row[1] << 8) | row[1];
- v = (row[2] << 8) | row[2];
- YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
- HISTOGRAM_TAIL(3)
- break;
- case BC_RGBA8888:
- HISTOGRAM_HEAD(unsigned char)
- r = (row[0] << 8) | row[0];
- g = (row[1] << 8) | row[1];
- b = (row[2] << 8) | row[2];
- HISTOGRAM_TAIL(4)
- break;
- case BC_RGBA_FLOAT:
- HISTOGRAM_HEAD(float)
- r = (int)(row[0] * 0xffff);
- g = (int)(row[1] * 0xffff);
- b = (int)(row[2] * 0xffff);
- HISTOGRAM_TAIL(4)
- break;
- case BC_YUVA8888:
- HISTOGRAM_HEAD(unsigned char)
- y = (row[0] << 8) | row[0];
- u = (row[1] << 8) | row[1];
- v = (row[2] << 8) | row[2];
- YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
- HISTOGRAM_TAIL(4)
- break;
- case BC_RGB161616:
- HISTOGRAM_HEAD(uint16_t)
- r = row[0];
- g = row[1];
- b = row[2];
- HISTOGRAM_TAIL(3)
- break;
- case BC_YUV161616:
- HISTOGRAM_HEAD(uint16_t)
- y = row[0];
- u = row[1];
- v = row[2];
- YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
- HISTOGRAM_TAIL(3)
- break;
- case BC_RGBA16161616:
- HISTOGRAM_HEAD(uint16_t)
- r = row[0];
- g = row[1];
- b = row[2];
- HISTOGRAM_TAIL(3)
- break;
- case BC_YUVA16161616:
- HISTOGRAM_HEAD(uint16_t)
- y = row[0];
- u = row[1];
- v = row[2];
- YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
- HISTOGRAM_TAIL(4)
- break;
+ int *preview_r = plugin->preview_lookup[HISTOGRAM_RED];
+ int *preview_g = plugin->preview_lookup[HISTOGRAM_GREEN];
+ int *preview_b = plugin->preview_lookup[HISTOGRAM_BLUE];
+
+ switch( data->get_color_model() ) {
+ case BC_RGB888:
+ HISTOGRAM_HEAD(unsigned char)
+ r = (row[0] << 8) | row[0];
+ g = (row[1] << 8) | row[1];
+ b = (row[2] << 8) | row[2];
+ HISTOGRAM_TAIL(3)
+ break;
+ case BC_RGB_FLOAT:
+ HISTOGRAM_HEAD(float)
+ r = (int)(row[0] * 0xffff);
+ g = (int)(row[1] * 0xffff);
+ b = (int)(row[2] * 0xffff);
+ HISTOGRAM_TAIL(3)
+ break;
+ case BC_YUV888:
+ HISTOGRAM_HEAD(unsigned char)
+ y = (row[0] << 8) | row[0];
+ u = (row[1] << 8) | row[1];
+ v = (row[2] << 8) | row[2];
+ YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
+ HISTOGRAM_TAIL(3)
+ break;
+ case BC_RGBA8888:
+ HISTOGRAM_HEAD(unsigned char)
+ r = (row[0] << 8) | row[0];
+ g = (row[1] << 8) | row[1];
+ b = (row[2] << 8) | row[2];
+ HISTOGRAM_TAIL(4)
+ break;
+ case BC_RGBA_FLOAT:
+ HISTOGRAM_HEAD(float)
+ r = (int)(row[0] * 0xffff);
+ g = (int)(row[1] * 0xffff);
+ b = (int)(row[2] * 0xffff);
+ HISTOGRAM_TAIL(4)
+ break;
+ case BC_YUVA8888:
+ HISTOGRAM_HEAD(unsigned char)
+ y = (row[0] << 8) | row[0];
+ u = (row[1] << 8) | row[1];
+ v = (row[2] << 8) | row[2];
+ YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
+ HISTOGRAM_TAIL(4)
+ break;
+ case BC_RGB161616:
+ HISTOGRAM_HEAD(uint16_t)
+ r = row[0];
+ g = row[1];
+ b = row[2];
+ HISTOGRAM_TAIL(3)
+ break;
+ case BC_YUV161616:
+ HISTOGRAM_HEAD(uint16_t)
+ y = row[0];
+ u = row[1];
+ v = row[2];
+ YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
+ HISTOGRAM_TAIL(3)
+ break;
+ case BC_RGBA16161616:
+ HISTOGRAM_HEAD(uint16_t)
+ r = row[0];
+ g = row[1];
+ b = row[2];
+ HISTOGRAM_TAIL(3)
+ break;
+ case BC_YUVA16161616:
+ HISTOGRAM_HEAD(uint16_t)
+ y = row[0];
+ u = row[1];
+ v = row[2];
+ YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);
+ HISTOGRAM_TAIL(4)
+ break;
}
- }
- 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; \
+ break; }
+ case HistogramEngine::APPLY: {
+
+#define PROCESS(type, components) { \
+ type **rows = (type**)input->get_rows(); \
+ for( int iy=pkg->start; iy<pkg->end; ++iy ) { \
+ type *row = rows[iy]; \
+ for( int ix=0; ix<w; ++ix ) { \
+ if( plugin->config.split && ((ix + (iy*w)/h) < w) ) \
+ continue; \
row[0] = lookup_r[row[0]]; \
row[1] = lookup_g[row[1]]; \
row[2] = lookup_b[row[2]]; \
} \
}
-#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) \
- { \
+#define PROCESS_YUV(type, components, max) { \
+ type **rows = (type**)input->get_rows(); \
+ for( int iy=pkg->start; iy<pkg->end; ++iy ) { \
+ type *row = rows[iy]; \
+ for( int ix=0; ix<w; ++ix ) { \
+ if( plugin->config.split && ((ix + (iy*w)/h) < w) ) \
+ continue; \
+ if( max == 0xff ) { /* Convert to 16 bit RGB */ \
y = (row[0] << 8) | row[0]; \
u = (row[1] << 8) | row[1]; \
v = (row[2] << 8) | row[2]; \
} \
- else \
- { \
+ else { \
y = row[0]; \
u = row[1]; \
v = row[2]; \
} \
- \
YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v); \
- \
/* Look up in RGB domain */ \
r = lookup_r[r]; \
g = lookup_g[g]; \
b = lookup_b[b]; \
- \
/* Convert to 16 bit YUV */ \
YUV::yuv.rgb_to_yuv_16(r, g, b, y, u, v); \
- \
- if(max == 0xff) \
- { \
+ if( max == 0xff ) { \
row[0] = y >> 8; \
row[1] = u >> 8; \
row[2] = v >> 8; \
} \
- else \
- { \
+ else { \
row[0] = y; \
row[1] = u; \
row[2] = v; \
} \
}
-#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_level(r, HISTOGRAM_RED, 1); \
- g = plugin->calculate_level(g, HISTOGRAM_GREEN, 1); \
- b = plugin->calculate_level(b, HISTOGRAM_BLUE, 1); \
- \
- row[0] = r; \
- row[1] = g; \
- row[2] = b; \
- \
+#define PROCESS_FLOAT(components) { \
+ float **rows = (float**)input->get_rows(); \
+ for( int iy=pkg->start; iy<pkg->end; ++iy ) { \
+ float *row = rows[iy]; \
+ for( int ix=0; ix<w; ++ix ) { \
+ if( plugin->config.split && ((ix + (iy*w)/h) < w) ) \
+ continue; \
+ float fr = row[0]; \
+ float fg = row[1]; \
+ float fb = row[2]; \
+ row[0] = plugin->calculate_level(fr, HISTOGRAM_RED, 1); \
+ row[1] = plugin->calculate_level(fg, HISTOGRAM_GREEN, 1); \
+ row[2] = plugin->calculate_level(fb, HISTOGRAM_BLUE, 1); \
row += components; \
} \
} \
}
-
VFrame *input = plugin->input;
//VFrame *output = plugin->output;
int w = input->get_w();
int *lookup_g = plugin->lookup[1];
int *lookup_b = plugin->lookup[2];
int r, g, b, y, u, v;
- switch(input->get_color_model())
- {
- case BC_RGB888:
- PROCESS(unsigned char, 3)
- break;
- case BC_RGB_FLOAT:
- PROCESS_FLOAT(3);
- break;
- case BC_RGBA8888:
- PROCESS(unsigned char, 4)
- break;
- case BC_RGBA_FLOAT:
- PROCESS_FLOAT(4);
- break;
- case BC_RGB161616:
- PROCESS(uint16_t, 3)
- break;
- case BC_RGBA16161616:
- PROCESS(uint16_t, 4)
- break;
- case BC_YUV888:
- PROCESS_YUV(unsigned char, 3, 0xff)
- break;
- case BC_YUVA8888:
- PROCESS_YUV(unsigned char, 4, 0xff)
- break;
- case BC_YUV161616:
- PROCESS_YUV(uint16_t, 3, 0xffff)
- break;
- case BC_YUVA16161616:
- PROCESS_YUV(uint16_t, 4, 0xffff)
- break;
+ switch( input->get_color_model() ) {
+ case BC_RGB888:
+ PROCESS(unsigned char, 3)
+ break;
+ case BC_RGB_FLOAT:
+ PROCESS_FLOAT(3);
+ break;
+ case BC_RGBA8888:
+ PROCESS(unsigned char, 4)
+ break;
+ case BC_RGBA_FLOAT:
+ PROCESS_FLOAT(4);
+ break;
+ case BC_RGB161616:
+ PROCESS(uint16_t, 3)
+ break;
+ case BC_RGBA16161616:
+ PROCESS(uint16_t, 4)
+ break;
+ case BC_YUV888:
+ PROCESS_YUV(unsigned char, 3, 0xff)
+ break;
+ case BC_YUVA8888:
+ PROCESS_YUV(unsigned char, 4, 0xff)
+ break;
+ case BC_YUV161616:
+ PROCESS_YUV(uint16_t, 3, 0xffff)
+ break;
+ case BC_YUVA16161616:
+ PROCESS_YUV(uint16_t, 4, 0xffff)
+ break;
}
+ break; }
}
}
-
-
-
-
HistogramEngine::HistogramEngine(HistogramMain *plugin,
- int total_clients,
- int total_packages)
+ int total_clients, int total_packages)
: LoadServer(total_clients, total_packages)
{
this->plugin = plugin;
void HistogramEngine::init_packages()
{
- switch(operation)
- {
- case HISTOGRAM:
- total_size = data->get_h();
- break;
- case APPLY:
- total_size = data->get_h();
- break;
+ 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++)
- {
+ int start = 0;
+ for( int i=0,n=get_total_packages(); i<n; ++i ) {
HistogramPackage *package = (HistogramPackage*)get_package(i);
- package->start = total_size * i / get_total_packages();
- package->end = total_size * (i + 1) / get_total_packages();
+ package->start = start;
+ package->end = total_size * (i+1)/n;
+ start = package->end;
}
// Initialize clients here in case some don't get run.
- for(int i = 0; i < get_total_clients(); i++)
- {
+ for( int i=0,n=get_total_clients(); i<n; ++i ) {
HistogramUnit *unit = (HistogramUnit*)get_client(i);
- for(int i = 0; i < HISTOGRAM_MODES; i++)
- bzero(unit->accum[i], sizeof(int) * HISTOGRAM_SLOTS);
+ for( int j=0; j<HISTOGRAM_MODES; ++j )
+ bzero(unit->accum[j], sizeof(int64_t) * HISTOGRAM_SLOTS);
}
-
}
LoadClient* HistogramEngine::new_client()