fixup a bunch of memory use issues
[goodguy/history.git] / cinelerra-5.0 / plugins / titler / title.C
index 4cc9745106bfb4bc8f252fe541596a7aa8d6954e..8ccdb2a3648bfa19b28afd2cfe45454a463bdde5 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "bcsignals.h"
 #include "clip.h"
-#include "colormodels.h"
+#include "bccmodels.h"
 #include "filexml.h"
 #include "filesystem.h"
 #include "transportque.inc"
@@ -86,7 +86,7 @@ TitleConfig::TitleConfig()
        fade_out = 0.0;
        x = 0.0;
        y = 0.0;
-       dropshadow = 10;
+       dropshadow = 2;
        sprintf(font, "fixed");
        sprintf(encoding, DEFAULT_ENCODING);
        timecode_format = DEFAULT_TIMECODEFORMAT;
@@ -204,8 +204,8 @@ void TitleConfig::interpolate(TitleConfig &prev,
 //     this->y = prev.y;
        timecode = prev.timecode;
        timecode_format = prev.timecode_format;
-//     this->dropshadow = (int)(prev.dropshadow * prev_scale + next.dropshadow * next_scale);
-       this->dropshadow = prev.dropshadow;
+       this->dropshadow = prev.dropshadow * prev_scale + next.dropshadow * next_scale;
+//     this->dropshadow = prev.dropshadow;
 }
 
 void TitleConfig::limits()
@@ -539,10 +539,14 @@ void TitleUnit::draw_glyph(VFrame *output, VFrame *data, TitleGlyph *glyph, int
        unsigned char **out_rows = output->get_rows();
 
        int baseline = plugin->get_char_height();
-       if(engine->do_dropshadow) {
+       if( engine->do_dropshadow ) {
                x += plugin->config.dropshadow;
                y += plugin->config.dropshadow;
        }
+       else if( plugin->config.dropshadow < 0 ) {
+               x -= plugin->config.dropshadow;
+               y -= plugin->config.dropshadow;
+       }
 
        int x_in = 0, y_in = 0;
        int x_out = x + glyph->left;
@@ -568,8 +572,8 @@ void TitleUnit::draw_glyph(VFrame *output, VFrame *data, TitleGlyph *glyph, int
 
        int r, g, b, a;
        plugin->get_color_components(&r, &g, &b, &a, 0);
-       int outline = plugin->config.outline_size;
-       if(outline) a = 0xff;
+       //int outline = plugin->config.outline_size;
+       //if(outline) a = 0xff;
 
        while( y_in < glyph_h && y_out < output_h ) {
                unsigned char *in_row = in_rows[y_in];
@@ -725,8 +729,6 @@ void TitleOutlineUnit::process_package(LoadPackage *package)
        TitleOutlinePackage *pkg = (TitleOutlinePackage*)package;
        int r, g, b, outline_a;
        plugin->get_color_components(&r, &g, &b, &outline_a, 1);
-       int title_r, title_g, title_b, title_a;
-       plugin->get_color_components(&title_r, &title_g, &title_b, &title_a, 0);
        unsigned char **outline_rows = plugin->outline_mask->get_rows();
        unsigned char **text_rows = plugin->text_mask->get_rows();
        int mask_w1 = plugin->text_mask->get_w()-1;
@@ -761,6 +763,7 @@ void TitleOutlineUnit::process_package(LoadPackage *package)
        }
        else {
 // Overlay text mask on top of outline mask
+               int ofs = BC_CModels::is_yuv(plugin->output->get_color_model()) ? 0x80 : 0;
                for(int y = pkg->y1; y < pkg->y2; y++) {
                        unsigned char *outline_row = outline_rows[y];
                        unsigned char *text_row = text_rows[y];
@@ -770,9 +773,9 @@ void TitleOutlineUnit::process_package(LoadPackage *package)
                                int out_a = out[3], in_a = inp[3];
                                int transparency = in_a * (0xff - out_a) / 0xff;
                                out[0] = (out[0] * out_a + inp[0] * transparency) / 0xff;
-                               out[1] = (out[1] * out_a + inp[1] * transparency) / 0xff;
-                               out[2] = (out[2] * out_a + inp[2] * transparency) / 0xff;
-                               out[3] = out_a + transparency;
+                               out[1] = ((out[1]-ofs) * out_a + (inp[1]-ofs) * transparency) / 0xff + ofs;
+                               out[2] = ((out[2]-ofs) * out_a + (inp[2]-ofs) * transparency) / 0xff + ofs;
+                               out[3] = in_a + out_a - in_a*out_a / 0xff;
                        }
                }
        }
@@ -815,7 +818,6 @@ LoadPackage* TitleOutlineEngine::new_package()
 
 
 
-
 TitleTranslatePackage::TitleTranslatePackage()
  : LoadPackage()
 {
@@ -847,8 +849,7 @@ void TitleTranslate::run_packages()
 
 
 
-
-#define TRANSLATE(type, max, components) \
+#define TRANSLATE(type, max, components, ofs) \
 { \
        unsigned char **in_rows = plugin->text_mask->get_rows(); \
        type **out_rows = (type**)plugin->output->get_rows(); \
@@ -885,10 +886,10 @@ void TitleTranslate::run_packages()
                                        x_fraction2 =  \
                                                server->x_table[j - server->out_x1_int].in_fraction2; \
  \
-                                       float fraction1 = x_fraction1 * y_fraction1; \
-                                       float fraction2 = x_fraction2 * y_fraction1; \
-                                       float fraction3 = x_fraction1 * y_fraction2; \
-                                       float fraction4 = x_fraction2 * y_fraction2; \
+                                       float fraction1 = x_fraction1 * y_fraction1 / (256.f-max); \
+                                       float fraction2 = x_fraction2 * y_fraction1 / (256.f-max); \
+                                       float fraction3 = x_fraction1 * y_fraction2 / (256.f-max); \
+                                       float fraction4 = x_fraction2 * y_fraction2 / (256.f-max); \
                                        type input_r = (type)(in_row1[in_x1 * 4 + 0] * fraction1 +  \
                                                                in_row1[in_x2 * 4 + 0] * fraction2 +  \
                                                                in_row2[in_x1 * 4 + 0] * fraction3 +  \
@@ -916,9 +917,9 @@ void TitleTranslate::run_packages()
                                                out_row[j * components + 0] =  \
                                                        (input_r * input_a + out_row[j * components + 0] * transparency) / max; \
                                                out_row[j * components + 1] =  \
-                                                       (input_g * input_a + out_row[j * components + 1] * transparency) / max; \
+                                                       ((input_g-ofs) * input_a + (out_row[j * components + 1]-ofs) * transparency) / max + ofs; \
                                                out_row[j * components + 2] =  \
-                                                       (input_b * input_a + out_row[j * components + 2] * transparency) / max; \
+                                                       ((input_b-ofs) * input_a + (out_row[j * components + 2]-ofs) * transparency) / max + ofs; \
                                                out_row[j * components + 3] =  \
                                                        MAX(input_a, out_row[j * components + 3]); \
                                        } \
@@ -928,9 +929,9 @@ void TitleTranslate::run_packages()
                                                out_row[j * components + 0] =  \
                                                        (input_r * input_a + out_row[j * components + 0] * transparency) / max; \
                                                out_row[j * components + 1] =  \
-                                                       (input_g * input_a + out_row[j * components + 1] * transparency) / max; \
+                                                       ((input_g-ofs) * input_a + (out_row[j * components + 1]-ofs) * transparency) / max + ofs; \
                                                out_row[j * components + 2] =  \
-                                                       (input_b * input_a + out_row[j * components + 2] * transparency) / max; \
+                                                       ((input_b-ofs) * input_a + (out_row[j * components + 2]-ofs) * transparency) / max + ofs; \
                                        } \
                                } \
                        } \
@@ -999,12 +1000,12 @@ void TitleTranslateUnit::process_package(LoadPackage *package)
        TitleTranslate *server = (TitleTranslate*)this->server;
 
        switch(plugin->output->get_color_model()) {
-       case BC_RGB888:     TRANSLATE(unsigned char, 0xff, 3); break;
-       case BC_RGB_FLOAT:  TRANSLATE(float, 1.0, 3);          break;
-       case BC_YUV888:     TRANSLATE(unsigned char, 0xff, 3); break;
-       case BC_RGBA_FLOAT: TRANSLATE(float, 1.0, 4);          break;
-       case BC_RGBA8888:   TRANSLATE(unsigned char, 0xff, 4); break;
-       case BC_YUVA8888:   TRANSLATE(unsigned char, 0xff, 4); break;
+       case BC_RGB888:     TRANSLATE(unsigned char, 0xff, 3, 0);    break;
+       case BC_RGB_FLOAT:  TRANSLATE(float, 1.0, 3, 0);             break;
+       case BC_YUV888:     TRANSLATE(unsigned char, 0xff, 3, 0x80); break;
+       case BC_RGBA_FLOAT: TRANSLATE(float, 1.0, 4, 0);             break;
+       case BC_RGBA8888:   TRANSLATE(unsigned char, 0xff, 4, 0);    break;
+       case BC_YUVA8888:   TRANSLATE(unsigned char, 0xff, 4, 0x80); break;
        }
 //printf("TitleTranslateUnit::process_package 5\n");
 }
@@ -1124,7 +1125,7 @@ TitleMain::~TitleMain()
        delete outline_engine;
 }
 
-const char* TitleMain::plugin_title() { return N_("Title"); }
+const char* TitleMain::plugin_title() { return _("Title"); }
 int TitleMain::is_realtime() { return 1; }
 int TitleMain::is_synthesis() { return 1; }
 
@@ -1202,10 +1203,12 @@ void TitleMain::build_previews(TitleWindow *gui)
                        for(int j = 0; j < len; j++)
                        {
                                FT_ULong c = test_string[j];
-                               check_char_code_path(freetype_library,
-                                       font_entry->path,
-                                       c,
-                                       (char *)new_path);
+// memory leaks here are fatal
+//                             check_char_code_path(freetype_library,
+//                                     font_entry->path,
+//                                     c,
+//                                     (char *)new_path);
+                               strcpy(new_path, font_entry->path);
                                if( !load_freetype_face(freetype_library,
                                        freetype_face, new_path)) {
                                        FT_Set_Pixel_Sizes(freetype_face, text_height, 0);
@@ -1213,11 +1216,11 @@ void TitleMain::build_previews(TitleWindow *gui)
                                        if(!FT_Load_Char(freetype_face, c, FT_LOAD_RENDER)) {
                                                if(pass == 0) {
                                                        current_w = current_x + freetype_face->glyph->bitmap.width;
-                                                       if(freetype_face->glyph->bitmap_top > current_ascent)
+                                                       if((int)freetype_face->glyph->bitmap_top > current_ascent)
                                                                current_ascent = freetype_face->glyph->bitmap_top;
-                                                       if(freetype_face->glyph->bitmap.rows > total_h)
+                                                       if((int)freetype_face->glyph->bitmap.rows > total_h)
                                                                total_h = freetype_face->glyph->bitmap.rows;
-                                                       if(freetype_face->glyph->bitmap.rows > current_h)
+                                                       if((int)freetype_face->glyph->bitmap.rows > current_h)
                                                                current_h = freetype_face->glyph->bitmap.rows;
                                                }
                                                else {
@@ -1226,7 +1229,7 @@ void TitleMain::build_previews(TitleWindow *gui)
                                                        int out_y = (total_h - height[font_number]) / 2 +
                                                                ascent[font_number] - freetype_face->glyph->bitmap_top;
                                                        for(int in_y = 0;
-                                                               in_y < freetype_face->glyph->bitmap.rows &&
+                                                               in_y < (int)freetype_face->glyph->bitmap.rows &&
                                                                        out_y < total_h;
                                                                in_y++, out_y++) {
                                                                unsigned char *out_row = font_entry->image->get_rows()[out_y] +
@@ -1234,7 +1237,7 @@ void TitleMain::build_previews(TitleWindow *gui)
                                                                unsigned char *in_row = freetype_face->glyph->bitmap.buffer +
                                                                        freetype_face->glyph->bitmap.pitch * in_y;
 
-                                                               for(int out_x = 0; out_x < freetype_face->glyph->bitmap.width &&
+                                                               for(int out_x = 0; out_x < (int)freetype_face->glyph->bitmap.width &&
                                                                        out_x < total_w;
                                                                        out_x++) {
                                                                        *out_row = (*in_row * r +
@@ -1300,7 +1303,7 @@ int TitleMain::check_char_code_path(FT_Library &freetype_library,
        {
                FT_Set_Pixel_Sizes(temp_freetype_face, 128, 0);
                int gindex = FT_Get_Char_Index(temp_freetype_face, char_code);
-               if((!gindex == 0) && (!char_code != 10))
+               if( gindex != 0 && char_code == 10 )
                {
                        strcpy(path_new, path_old);
                        notfindit = 0;
@@ -1326,7 +1329,7 @@ int TitleMain::check_char_code_path(FT_Library &freetype_library,
                                        {
                                                FT_Set_Pixel_Sizes(temp_freetype_face, 128, 0);
                                                int gindex = FT_Get_Char_Index(temp_freetype_face, char_code);
-                                               if((!gindex == 0) && (!char_code != 10))
+                                               if( gindex != 0 && char_code == 10 )
                                                {
                                                        sprintf(path_new, "%s", tmpstring);
                                                        notfindit = 0;
@@ -1735,8 +1738,8 @@ int TitleMain::draw_mask()
 
        extent.x1 -= config.outline_size*2;
        extent.y1 -= config.outline_size*2;
-       extent.x2 += config.dropshadow + config.outline_size*2;
-       extent.y2 += config.dropshadow + config.outline_size*2;
+       extent.x2 += abs(config.dropshadow) + config.outline_size*2;
+       extent.y2 += abs(config.dropshadow) + config.outline_size*2;
 
        // Determine mask geometry
        mask_w = extent.x2 - extent.x1;
@@ -1760,7 +1763,7 @@ int TitleMain::draw_mask()
                text_mask = new VFrame;
                text_mask->set_use_shm(0);
                text_mask->reallocate(0, -1, 0, 0, 0, mask_w, mask_h, color_model, -1);
-               int drop = !config.dropshadow ? 0 : config.dropshadow;
+               float drop = abs(config.dropshadow);
                int drop_w = mask_w + drop;
                int drop_h = mask_h + drop;
                 text_mask_stroke = new VFrame;
@@ -1887,35 +1890,22 @@ void TitleMain::overlay_mask()
 
 void TitleMain::get_color_components(int *r, int *g, int *b, int *a, int is_outline)
 {
-       int r_in, g_in, b_in, a_in;
-
-       if(is_outline)
-       {
-               r_in = (config.outline_color & 0xff0000) >> 16;
-               g_in = (config.outline_color & 0xff00) >> 8;
-               b_in = config.outline_color & 0xff;
-               a_in = config.outline_alpha;
-       }
-       else
-       {
-               r_in = (config.color & 0xff0000) >> 16;
-               g_in = (config.color & 0xff00) >> 8;
-               b_in = config.color & 0xff;
-               a_in = config.alpha;
-       }
-       *r = r_in;
-       *g = g_in;
-       *b = b_in;
-       *a = a_in;
+       int color = is_outline ? config.outline_color : config.color;
+       unsigned char r_in = color >> 16;
+       unsigned char g_in = color >> 8;
+       unsigned char b_in = color;
+       *a = is_outline ? config.outline_alpha : config.alpha;
 
-       switch(output->get_color_model())
-       {
+       switch(output->get_color_model()) {
                case BC_YUV888:
                        yuv.rgb_to_yuv_8(r_in, g_in, b_in, *r, *g, *b);
                        break;
                case BC_YUVA8888:
                        yuv.rgb_to_yuv_8(r_in, g_in, b_in, *r, *g, *b);
                        break;
+               default:
+                       *r = r_in;  *g = g_in;  *b = b_in;
+                       break;
        }
 }