X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2FC41%2Fc41.C;h=6006e07b0060fb634731c21b55296f67a0b858e4;hb=667ff598ae2a94f48c7056aee1d77d7cde39066b;hp=32f5afe322faec964013338e4175bf0047a5ec2f;hpb=47462c7a88ed4f844fa4eaf32a84533aa847b7d5;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/plugins/C41/c41.C b/cinelerra-5.1/plugins/C41/c41.C index 32f5afe3..6006e07b 100644 --- a/cinelerra-5.1/plugins/C41/c41.C +++ b/cinelerra-5.1/plugins/C41/c41.C @@ -18,7 +18,7 @@ * */ #include "c41.h" -#include "cicolors.h" +#include "bccolors.h" #include "clip.h" #include "edlsession.h" #include "filexml.h" @@ -165,7 +165,7 @@ int C41Button::handle_event() C41BoxButton::C41BoxButton(C41Effect *plugin, C41Window *window, int x, int y) - : BC_GenericButton(x, y, _("Apply box")) + : BC_GenericButton(x, y, _("Apply default box")) { this->plugin = plugin; this->window = window; @@ -267,11 +267,11 @@ C41Window::C41Window(C41Effect *plugin) add_subwindow(gamma_b = new BC_Title(x + 80, y, "0.0000")); y += 30; - add_subwindow(new BC_Title(x, y, _("Coef 1:"))); + add_subwindow(new BC_Title(x, y, _("Contrast:"))); add_subwindow(coef1 = new BC_Title(x + 80, y, "0.0000")); y += 30; - add_subwindow(new BC_Title(x, y, _("Coef 2:"))); + add_subwindow(new BC_Title(x, y, _("Brightness:"))); add_subwindow(coef2 = new BC_Title(x + 80, y, "0.0000")); y += 30; @@ -334,12 +334,12 @@ C41Window::C41Window(C41Effect *plugin) &plugin->config.fix_gamma_b, x + 80, y)); y += 30; - add_subwindow(new BC_Title(x, y, _("Coef 1:"))); + add_subwindow(new BC_Title(x, y, _("Contrast:"))); add_subwindow(fix_coef1 = new C41TextBox(plugin, &plugin->config.fix_coef1, x + 80, y)); y += 30; - add_subwindow(new BC_Title(x, y, _("Coef 2:"))); + add_subwindow(new BC_Title(x, y, _("Brightness:"))); add_subwindow(fix_coef2 = new C41TextBox(plugin, &plugin->config.fix_coef2, x + 80, y)); y += 30; @@ -430,6 +430,11 @@ C41Effect::C41Effect(PluginServer *server) tmp_frame = 0; blurry_frame = 0; memset(&values, 0, sizeof(values)); + shave_min_row = shave_max_row = 0; + shave_min_col = shave_max_col = 0; + min_col = max_col = 0; + min_row = max_row = 0; + pix_max = 0; pix_len = 0; } C41Effect::~C41Effect() @@ -545,6 +550,21 @@ float C41Effect::myPow(float a, float b) #endif +void C41Effect::pix_fix(float &pix, float min, float gamma) +{ + float val = pix; + if( val >= 1e-3 ) { + val = min / val; + if( gamma != 1 ) val = POWF(val, gamma); + bclamp(val -= config.fix_light, 0, pix_max); + if( config.postproc ) + val = config.fix_coef1 * val + config.fix_coef2; + } + else + val = 1; + pix = val; +} + int C41Effect::process_realtime(VFrame *input, VFrame *output) { load_configuration(); @@ -599,9 +619,9 @@ int C41Effect::process_realtime(VFrame *input, VFrame *output) for( int i=0; i=0; row+=pix_len ) { - *tmp++ = fix_exepts(row[0]); - *tmp++ = fix_exepts(row[1]); - *tmp++ = fix_exepts(row[2]); + *tmp++ = bclip(row[0], 0, pix_max); + *tmp++ = bclip(row[1], 0, pix_max); + *tmp++ = bclip(row[2], 0, pix_max); } } @@ -707,118 +727,115 @@ int C41Effect::process_realtime(VFrame *input, VFrame *output) if( row[2] > maxima_b ) maxima_b = row[2]; } } - if( minima_r < 1e-6 ) minima_r = 1e-6; - if( minima_g < 1e-6 ) minima_g = 1e-6; - if( minima_b < 1e-6 ) minima_b = 1e-6; values.min_r = minima_r; values.max_r = maxima_r; values.min_g = minima_g; values.max_g = maxima_g; values.min_b = minima_b; values.max_b = maxima_b; values.light = maxima_r < 1e-6 ? 1.0 : minima_r / maxima_r; - values.gamma_g = logf(maxima_r / minima_r) / logf(maxima_g / minima_g); - values.gamma_b = logf(maxima_r / minima_r) / logf(maxima_b / minima_b); + bclamp(minima_r, 1e-6, 1-1e-6); bclamp(maxima_r, 1e-6, 1-1e-6); + bclamp(minima_g, 1e-6, 1-1e-6); bclamp(maxima_g, 1e-6, 1-1e-6); + bclamp(minima_b, 1e-6, 1-1e-6); bclamp(maxima_b, 1e-6, 1-1e-6); + float log_r = logf(maxima_r / minima_r); + float log_g = logf(maxima_g / minima_g); + float log_b = logf(maxima_b / minima_b); + if( log_g < 1e-6 ) log_g = 1e-6; + if( log_b < 1e-6 ) log_b = 1e-6; + values.gamma_g = log_r / log_g; + values.gamma_b = log_r / log_b; values.shave_min_col = shave_min_col; values.shave_max_col = shave_max_col; values.shave_min_row = shave_min_row; values.shave_max_row = shave_max_row; - values.coef1 = -1; - values.coef2 = -1; + values.coef1 = values.coef2 = -1; // Update GUI send_render_gui(&values); } + if( config.compute_magic ) { + float minima_r = 50., minima_g = 50., minima_b = 50.; + float maxima_r = 0., maxima_g = 0., maxima_b = 0.; + + for( int i = min_row; i < max_row; i++ ) { + float *row = (float*)frame->get_rows()[i]; + row += 3 * min_col; + for( int j = min_col; j < max_col; j++, row += 3 ) { + if( row[0] < minima_r ) minima_r = row[0]; + if( row[0] > maxima_r ) maxima_r = row[0]; + + if( row[1] < minima_g ) minima_g = row[1]; + if( row[1] > maxima_g ) maxima_g = row[1]; + + if( row[2] < minima_b ) minima_b = row[2]; + if( row[2] > maxima_b ) maxima_b = row[2]; + } + } + + // Calculate postprocessing coeficents + values.coef2 = minima_r; + if( minima_g < values.coef2 ) values.coef2 = minima_g; + if( minima_b < values.coef2 ) values.coef2 = minima_b; + values.coef1 = maxima_r; + if( maxima_g > values.coef1 ) values.coef1 = maxima_g; + if( maxima_b > values.coef1 ) values.coef1 = maxima_b; + // Try not to overflow RGB601 (235 - 16) / 256 * 0.9 + float den = values.coef1 - values.coef2; + if( fabs(den) < 1e-6 ) den = 1e-6; + values.coef1 = 0.770 / den; + values.coef2 = 0.065 - values.coef2 * values.coef1; + send_render_gui(&values); + } + // Apply the transformation if( config.active ) { for( int i = 0; i < frame_h; i++ ) { float *row = (float*)frame->get_rows()[i]; for( int j = 0; j < frame_w; j++, row += pix_len ) { - float r0 = row[0] >= 1e-6 ? row[0] : 1e-6; - float v0 = config.fix_min_r / r0 - config.fix_light; - row[0] = normalize_pixel(v0 - config.fix_light); - float r1 = row[1] >= 1e-6 ? row[1] : 1e-6; - float v1 = POWF((config.fix_min_g / r1), config.fix_gamma_g); - row[1] = normalize_pixel(v1 - config.fix_light); - float r2 = row[2] >= 1e-6 ? row[2] : 1e-6; - float v2 = POWF((config.fix_min_b / r2), config.fix_gamma_b); - row[2] = normalize_pixel(v2 - config.fix_light); - } - } - if( config.compute_magic && !config.postproc ) { - float minima_r = 50., minima_g = 50., minima_b = 50.; - float maxima_r = 0., maxima_g = 0., maxima_b = 0.; - - for( int i = min_row; i < max_row; i++ ) { - float *row = (float*)frame->get_rows()[i]; - row += 3 * shave_min_col; - for( int j = min_col; j < max_col; j++, row += 3 ) { - if( row[0] < minima_r ) minima_r = row[0]; - if( row[0] > maxima_r ) maxima_r = row[0]; - - if( row[1] < minima_g ) minima_g = row[1]; - if( row[1] > maxima_g ) maxima_g = row[1]; - - if( row[2] < minima_b ) minima_b = row[2]; - if( row[2] > maxima_b ) maxima_b = row[2]; - } + pix_fix(row[0], config.fix_min_r, 1); + pix_fix(row[1], config.fix_min_g, config.fix_gamma_g); + pix_fix(row[2], config.fix_min_b, config.fix_gamma_b); } - - // Calculate postprocessing coeficents - values.coef2 = minima_r; - if( minima_g < values.coef2 ) - values.coef2 = minima_g; - if( minima_b < values.coef2 ) - values.coef2 = minima_b; - values.coef1 = maxima_r; - if( maxima_g > values.coef1 ) - values.coef1 = maxima_g; - if( maxima_b > values.coef1 ) - values.coef1 = maxima_b; - // Try not to overflow RGB601 - // (235 - 16) / 256 * 0.9 - float den = values.coef1 - values.coef2; - if( fabs(den) < 1e-6 ) - den = den < 0 ? -1e-6 : 1e-6; - values.coef1 = 0.770 / den; - values.coef2 = 0.065 - values.coef2 * values.coef1; - send_render_gui(&values); } } if( config.show_box ) { - float **rows = (float **)frame->get_rows(); - if( min_row < max_row - 1 ) { - float *row1 = (float *)rows[min_row]; - float *row2 = (float *)rows[max_row - 1]; - - for( int i = 0; i < frame_w; i++ ) { - for( int j = 0; j < 3; j++ ) { - row1[j] = pix_max - row1[j]; - row2[j] = pix_max - row2[j]; - } - if( has_alpha ) { - row1[3] = pix_max; - row2[3] = pix_max; + EDLSession *session = get_edlsession(); + int line_w = bmax(session->output_w,session->output_h) / 600 + 1; + for( int k=0; kget_rows(); + if( min_row < max_row - 1 ) { + float *row1 = (float *)rows[min_row+k]; + float *row2 = (float *)rows[max_row-k - 1]; + + for( int i = 0; i < frame_w; i++ ) { + for( int j = 0; j < 3; j++ ) { + row1[j] = pix_max - row1[j]; + row2[j] = pix_max - row2[j]; + } + if( has_alpha ) { + row1[3] = pix_max; + row2[3] = pix_max; + } + row1 += pix_len; + row2 += pix_len; } - row1 += pix_len; - row2 += pix_len; } - } - - if( min_col < max_col - 1 ) { - int pix1 = pix_len * min_col; - int pix2 = pix_len * (max_col - 1); - - for( int i = 0; i < frame_h; i++ ) { - float *row1 = rows[i] + pix1; - float *row2 = rows[i] + pix2; - for( int j = 0; j < 3; j++ ) { - row1[j] = pix_max - row1[j]; - row2[j] = pix_max - row2[j]; - } - if( has_alpha ) { - row1[3] = pix_max; - row2[3] = pix_max; + if( min_col < max_col - 1 ) { + int pix1 = pix_len * (min_col+k); + int pix2 = pix_len * (max_col-k - 1); + + for( int i = 0; i < frame_h; i++ ) { + float *row1 = rows[i] + pix1; + float *row2 = rows[i] + pix2; + + for( int j = 0; j < 3; j++ ) { + row1[j] = pix_max - row1[j]; + row2[j] = pix_max - row2[j]; + } + if( has_alpha ) { + row1[3] = pix_max; + row2[3] = pix_max; + } } } } @@ -832,24 +849,3 @@ int C41Effect::process_realtime(VFrame *input, VFrame *output) return 0; } -float C41Effect::normalize_pixel(float ival) -{ - float val = fix_exepts(ival); - - if( config.postproc ) - val = config.fix_coef1 * val + config.fix_coef2; - - CLAMP(val, 0., pix_max); - return val; -} - -float C41Effect::fix_exepts(float ival) -{ - switch( fpclassify(ival) ) { - case FP_NAN: - case FP_SUBNORMAL: return 0; - case FP_INFINITE: return ival < 0 ? 0 : pix_max; - } - return ival; -} -