X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Fhistogram%2Fhistogram.C;h=c78c3c7c44eb3b44c547de8f81059dd7f4ba7b68;hb=c7754a695f7750177de8645709f5d30487a4ac45;hp=a2cf0c987e555dca592ee089ff6bdb45656a7f0b;hpb=232ae3c6972c1740b6e1890ccce1264f2bb311f5;p=goodguy%2Fcinelerra.git diff --git a/cinelerra-5.1/plugins/histogram/histogram.C b/cinelerra-5.1/plugins/histogram/histogram.C index a2cf0c98..c78c3c7c 100644 --- a/cinelerra-5.1/plugins/histogram/histogram.C +++ b/cinelerra-5.1/plugins/histogram/histogram.C @@ -62,23 +62,24 @@ HistogramMain::HistogramMain(PluginServer *server) : PluginVClient(server) { engine = 0; - stripe_engine = 0; for( int i=0; iwindow)->lock_window("HistogramMain::render_gui 1"); - tabulate_curve(HISTOGRAM_RED, 0); - tabulate_curve(HISTOGRAM_GREEN, 0); - tabulate_curve(HISTOGRAM_BLUE, 0); - tabulate_curve(preview_lookup, HISTOGRAM_RED, 0x10000, 0); - tabulate_curve(preview_lookup, HISTOGRAM_GREEN, 0x10000, 0); - tabulate_curve(preview_lookup, HISTOGRAM_BLUE, 0x10000, 0); - ((HistogramWindow*)thread->window)->unlock_window(); - } - - calculate_histogram(input, !config.automatic); - - if( config.automatic ) { - calculate_automatic(input); -// 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); - tabulate_curve(preview_lookup, HISTOGRAM_RED, 0x10000, 0); - tabulate_curve(preview_lookup, HISTOGRAM_GREEN, 0x10000, 0); - tabulate_curve(preview_lookup, HISTOGRAM_BLUE, 0x10000, 0); - ((HistogramWindow*)thread->window)->unlock_window(); -// Need a second pass to get the luminance values. - calculate_histogram(input, 1); - } - - ((HistogramWindow*)thread->window)->lock_window("HistogramMain::render_gui 2"); -// 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(); + if( !thread ) return; + HistogramWindow *window = (HistogramWindow*)thread->window; + HistogramMain *plugin = (HistogramMain*)data; +//update gui client instance, needed for drawing + for( int i=0; iconfig.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 + 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() @@ -166,7 +137,6 @@ void HistogramMain::update_gui() 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"); @@ -176,8 +146,8 @@ void HistogramMain::save_data(KeyFrame *keyframe) 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("FRAMES", config.frames); output.tag.set_property("LOG_SLIDER", config.log_slider); output.tag.set_property("W", w); output.tag.set_property("H", h); @@ -216,8 +186,8 @@ void HistogramMain::read_data(KeyFrame *keyframe) 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.frames = input.tag.get_property("FRAMES", config.frames); config.log_slider = input.tag.get_property("LOG_SLIDER", config.log_slider); if( is_defaults() ) { @@ -289,21 +259,22 @@ void HistogramMain::calculate_histogram(VFrame *data, int do_value) if( cpus > smps ) cpus = smps; engine = new HistogramEngine(this, cpus, cpus); } - if( !accum[0] ) { - for( int i=0; iprocess_packages(HistogramEngine::HISTOGRAM, data, do_value); + int k = 0; HistogramUnit *unit = (HistogramUnit*)engine->get_client(0); - for( int i=0; iaccum[i], sizeof(int)*HISTOGRAM_SLOTS); + if( !sum_frames ) { + frames = 0; + for( int i=0; iaccum[i], sizeof(int64_t)*HISTOGRAM_SLOTS); + k = 1; + } - for( int i=1,n=engine->get_total_clients(); iget_total_clients(); iget_client(i); for( int j=0; jaccum[j], *out = accum[j]; + int64_t *in = unit->accum[j], *out = accum[j]; for( int k=HISTOGRAM_SLOTS; --k>=0; ) *out++ += *in++; } } @@ -314,6 +285,7 @@ void HistogramMain::calculate_histogram(VFrame *data, int do_value) accum[i][0] = 0; accum[i][HISTOGRAM_SLOTS - 1] = 0; } + ++frames; } @@ -324,14 +296,16 @@ void HistogramMain::calculate_automatic(VFrame *data) // Do each channel for( int i=0; i<3; ++i ) { - int *accum = this->accum[i]; - int pixels = data->get_w() * data->get_h(); + 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); float min_level = 0.0, max_level = 1.0; // Get histogram slot above threshold of pixels - for( int j=0, total=0; j= threshold ) { max_level = (float)j / HISTOGRAM_SLOTS * FLOAT_RANGE + HIST_MIN_INPUT; @@ -339,8 +313,9 @@ void HistogramMain::calculate_automatic(VFrame *data) } } -// Get slot below 99% of pixels - for( int j=HISTOGRAM_SLOTS, total=0; --j> 0; ) { +// Get histogram slot below threshold of pixels + total = 0; + for( int j=HISTOGRAM_SLOTS; --j> 0; ) { total += accum[j]; if( total >= threshold ) { min_level = (float)j / HISTOGRAM_SLOTS * FLOAT_RANGE + HIST_MIN_INPUT; @@ -368,100 +343,34 @@ int HistogramMain::process_buffer(VFrame *frame, int64_t start_position, double frame_rate) { - int need_reconfigure = load_configuration(); + need_reconfigure = load_configuration(); int use_opengl = calculate_use_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 ) { + if( !engine ) 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); } - int frames = config.frames; - MWindow *mwindow = server->mwindow; - if( frames > 1 && (!mwindow || // dont scan during SELECT_REGION - mwindow->session->current_operation != SELECT_REGION || - mwindow->edl->local_session->get_selectionstart() == - mwindow->edl->local_session->get_selectionend() ) ) { - if( !stripe_engine ) - stripe_engine = new HistStripeEngine(this, cpus, cpus); - int fw = frame->get_w(), fh =frame->get_h(); - new_temp(fw, fh, BC_RGB_FLOAT); - MWindow *mwindow = server->mwindow; - if( (mwindow && mwindow->session->current_operation == SELECT_REGION) || - ( last_frames == frames && last_position-1 == start_position && - fframe && fframe->get_w() == fw && fframe->get_h() == fh ) ) { - read_frame(temp, 0, start_position, frame_rate, use_opengl); - stripe_engine->process_packages(ADD_FFRM); - frame->transfer_from(temp); - } - else if( last_frames != frames || last_position != start_position || - !fframe || fframe->get_w() != fw || fframe->get_h() != fh ) { - last_frames = frames; - last_position = start_position; - VFrame::get_temp(fframe, fw, fh, BC_RGB_FLOAT); - read_frame(fframe, 0, start_position+1, frame_rate, use_opengl); - BC_ProgressBox *progress = 0; - const char *progress_title = _("Histogram: scanning\n"); - Timer timer; - for( int i=2; iprocess_packages(ADD_TEMP); - if( !progress && gui_open() && frames > 2*frame_rate ) { - progress = new BC_ProgressBox(-1, -1, progress_title, frames); - progress->start(); - } - if( progress && timer.get_difference() > 100 ) { - timer.update(); - progress->update(i, 1); - char string[BCTEXTLEN]; - sprintf(string, "%sframe: %d", progress_title, i); - progress->update_title(string, 1); - if( progress->is_cancelled() ) break; - } - if( progress && !gui_open() ) { - progress->stop_progress(); - delete progress; progress = 0; - } - } - read_frame(temp, 0, start_position, frame_rate, use_opengl); - stripe_engine->process_packages(ADD_FFRMS); - frame->transfer_from(temp); - if( progress ) { - progress->stop_progress(); - delete progress; - } - ++last_position; - } - else { - read_frame(temp, 0, start_position+frames-1, frame_rate, use_opengl); - stripe_engine->process_packages(ADD_TEMPS); - frame->transfer_from(fframe); - read_frame(temp, 0, start_position, frame_rate, use_opengl); - stripe_engine->process_packages(SUB_TEMPS); - ++last_position; - } - } - else - read_frame(frame, 0, start_position, frame_rate, use_opengl); -// if to plot histogram - if(config.plot) 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); } // Apply histogram in hardware @@ -473,24 +382,26 @@ int HistogramMain::process_buffer(VFrame *frame, return 0; } -void HistogramMain::tabulate_curve(int **table, int idx, int len, int use_value) +void HistogramMain::tabulate_curve(int **table, int idx, int use_value, int len) { - if( !table[idx] ) // must use max demand here - table[idx] = new int[0x10000]; - int *curve = table[idx], len1 = len-1; + int len1 = len - 1; + int *curve = table[idx]; for( int i=0; iget_color_model(); - int lookup_len = color_model == BC_RGB888 || - color_model == BC_RGBA8888 ? 0x100 : 0x10000; - tabulate_curve(lookup, idx, lookup_len, use_value); + 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() @@ -750,121 +661,6 @@ int HistogramMain::handle_opengl() } -HistStripePackage::HistStripePackage() - : LoadPackage() -{ -} - -HistStripeUnit::HistStripeUnit(HistStripeEngine *server, HistogramMain *plugin) - : LoadClient(server) -{ - this->plugin = plugin; - this->server = server; -} - -void HistStripeUnit::process_package(LoadPackage *package) -{ - HistStripePackage *pkg = (HistStripePackage*)package; - int frames = plugin->config.frames; - float scale = 1. / frames; - int iy0 = pkg->y0, iy1 = pkg->y1; - int fw = plugin->fframe->get_w(); - uint8_t **frows = plugin->fframe->get_rows(); - uint8_t **trows = plugin->temp->get_rows(); - switch( server->operation ) { - case ADD_TEMP: // add temp to fframe - for( int iy=iy0; iyplugin = plugin; -} -void HistStripeEngine::init_packages() -{ - int ih = plugin->input->get_h(), iy0 = 0; - for( int i=0,n=get_total_packages(); iy0 = iy0; pkg->y1 = iy1; - iy0 = iy1; - } -} - -LoadClient* HistStripeEngine::new_client() -{ - return new HistStripeUnit(this, plugin); -} - -LoadPackage* HistStripeEngine::new_package() -{ - return new HistStripePackage(); -} - -void HistStripeEngine::process_packages(int operation) -{ - this->operation = operation; - LoadServer::process_packages(); -} - - - HistogramPackage::HistogramPackage() : LoadPackage() { @@ -877,7 +673,7 @@ HistogramUnit::HistogramUnit(HistogramEngine *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() @@ -908,7 +704,7 @@ void HistogramUnit::process_package(LoadPackage *package) b_out = preview_b[bclip(b, 0, 0xffff)]; \ /* v = (r * 76 + g * 150 + b * 29) >> 8; */ \ /* Value takes the maximum of the output RGB values */ \ - v = MAX(r_out, g_out); v = MAX(v, b_out); \ + int v = MAX(r_out, g_out); v = MAX(v, b_out); \ ++accum_v[bclip(v -= hmin, 0, slots1)]; \ } \ \ @@ -923,10 +719,10 @@ void HistogramUnit::process_package(LoadPackage *package) 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 *preview_r = plugin->preview_lookup[HISTOGRAM_RED]; @@ -1159,7 +955,7 @@ void HistogramEngine::init_packages() for( int i=0,n=get_total_clients(); iaccum[j], sizeof(int) * HISTOGRAM_SLOTS); + bzero(unit->accum[j], sizeof(int64_t) * HISTOGRAM_SLOTS); } }