plug leaks, leaker tweaks, lang for effect info, c41 spiffs, wm probe tweaks
[goodguy/history.git] / cinelerra-5.1 / plugins / C41 / c41.C
index 6a3829354c49b3930bf846d0d542784f8cd3e9a4..b7160b75c79cdd233c25a7c3c2d3956a8e405844 100644 (file)
@@ -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;
@@ -545,6 +545,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 +614,9 @@ int C41Effect::process_realtime(VFrame *input, VFrame *output)
                for( int i=0; i<frame_h; ++i ) {
                        float *row = rows[i], *tmp = tmp_rows[i];
                        for( int j=frame_w; --j>=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);
                        }
                }
 
@@ -731,92 +746,91 @@ int C41Effect::process_realtime(VFrame *input, VFrame *output)
                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 * 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];
+                       }
+               }
+
+               // 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 = 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 j=0; j<line_w; ++j ) {
+                       float **rows = (float **)frame->get_rows();
+                       if( min_row < max_row - 1 ) {
+                               float *row1 = (float *)rows[min_row+j];
+                               float *row2 = (float *)rows[max_row-j - 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+j;
+                               int pix2 = pix_len * (max_col-j - 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;
+                                       }
                                }
                        }
                }
@@ -830,24 +844,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;
-}
-