void MWindow::init_plugin_tips(ArrayList<PluginServer*> &plugins, const char *lang)
{
const char *cfg_path = File::get_cindat_path();
- char msg_path[BCTEXTLEN]; int txt = 0;
+ char msg_path[BCTEXTLEN];
FILE *fp = 0;
if( BC_Resources::language[0] ) {
snprintf(msg_path, sizeof(msg_path), "%s/info/plugins.%s",
fp = fopen(msg_path, "r");
}
if( !fp ) {
- txt = 1;
snprintf(msg_path, sizeof(msg_path), "%s/info/plugins.txt",
cfg_path);
fp = fopen(msg_path, "r");
if( done ) {
if( tp > text && *--tp == '\n' ) *tp = 0;
if( title[0] ) {
- tp = !txt ? title : _(title);
int idx = plugins.size();
- while( --idx>=0 && strcmp(plugins[idx]->title, tp) );
+ while( --idx>=0 && strcmp(plugins[idx]->title, title) );
if( idx >= 0 ) {
delete [] plugins[idx]->tip;
plugins[idx]->tip = cstrdup(text);
: BC_Window(client->gui_string,
client->window_x /* - w / 2 */,
client->window_y /* - h / 2 */,
- w, h, min_w, min_h, allow_resize, 0, 1)
+ (int)(w*get_resources()->font_scale+0.5), (int)(h*get_resources()->font_scale+0.5),
+ (int)(min_w*get_resources()->font_scale+0.5), (int)(min_h*get_resources()->font_scale+0.5),
+ allow_resize, 0, 1)
{
this->client = client;
}
PluginClientWindow::PluginClientWindow(const char *title,
int x, int y, int w, int h, int min_w, int min_h, int allow_resize)
- : BC_Window(title, x, y, w, h, min_w, min_h, allow_resize, 0, 1)
+ : BC_Window(title, x, y,
+ (int)(w*get_resources()->font_scale+0.5), (int)(h*get_resources()->font_scale+0.5),
+ (int)(min_w*get_resources()->font_scale+0.5), (int)(min_h*get_resources()->font_scale+0.5),
+ allow_resize, 0, 1)
{
this->client = 0;
}
ViewPopup *VIconThread::new_view_window(VFrame *frame)
{
- int wx = viewing->get_vx() - view_w, rx = 0;
- int wy = viewing->get_vy() - view_h, ry = 0;
- wdw->get_root_coordinates(wx, wy, &rx, &ry);
+ BC_WindowBase *parent = wdw->get_parent();
+ XineramaScreenInfo *info = parent->get_xinerama_info(-1);
+ int cx = info ? info->x_org + info->width/2 : parent->get_root_w(0)/2;
+ int cy = info ? info->y_org + info->height/2 : parent->get_root_h(0)/2;
+ int vx = viewing->get_vx(), rx = 0;
+ int vy = viewing->get_vy(), ry = 0;
+ wdw->get_root_coordinates(vx, vy, &rx, &ry);
+ rx += (rx >= cx ? -view_w : viewing->vw);
+ ry += (ry >= cy ? -view_h : viewing->vh);
ViewPopup *vwin = new ViewPopup(this, frame, rx, ry, view_w, view_h);
wdw->set_active_subwindow(vwin);
return vwin;
#include <string.h>
#include <unistd.h>
-
-
-
-
-
REGISTER_PLUGIN(AgingMain)
+int AgingMain::dx[] = { 1, 1, 0, -1, -1, -1, 0, 1 };
+int AgingMain::dy[] = { 0, -1, -1, -1, 0, 1, 1, 1 };
+AgingMain::AgingMain(PluginServer *server)
+ : PluginVClient(server)
+{
+ aging_server = 0;
+ pits_count = 0;
+ dust_count = 0;
+}
+AgingMain::~AgingMain()
+{
+ delete aging_server;
+}
+const char* AgingMain::plugin_title() { return N_("AgingTV"); }
+int AgingMain::is_realtime() { return 1; }
-int AgingConfig::dx[] = { 1, 1, 0, -1, -1, -1, 0, 1};
-int AgingConfig::dy[] = { 0, -1, -1, -1, 0, 1, 1, 1};
-
-AgingConfig::AgingConfig()
+void AgingConfig::reset()
{
+ area_scale = 10;
+ aging_mode = 0;
dust_interval = 0;
pits_interval = 0;
- aging_mode = 0;
- area_scale = 10;
scratch_lines = 7;
colorage = 1;
scratch = 1;
dust = 1;
}
-AgingMain::AgingMain(PluginServer *server)
- : PluginVClient(server)
+AgingConfig::AgingConfig()
{
-
- aging_server = 0;
+ reset();
}
-AgingMain::~AgingMain()
+AgingConfig::~AgingConfig()
{
-
- if(aging_server) delete aging_server;
}
-const char* AgingMain::plugin_title() { return N_("AgingTV"); }
-int AgingMain::is_realtime() { return 1; }
-
-NEW_WINDOW_MACRO(AgingMain, AgingWindow)
-
-int AgingMain::load_defaults()
+int AgingConfig::equivalent(AgingConfig &that)
{
- return 0;
+ return area_scale == that.area_scale &&
+ aging_mode == that.aging_mode &&
+ dust_interval == that.dust_interval &&
+ pits_interval == that.pits_interval &&
+ scratch_lines == that.scratch_lines &&
+ colorage == that.colorage &&
+ scratch == that.scratch &&
+ pits == that.pits &&
+ dust == that.dust;
}
-int AgingMain::save_defaults()
+void AgingConfig::copy_from(AgingConfig &that)
{
- return 0;
+ area_scale = that.area_scale;
+ aging_mode = that.aging_mode;
+ dust_interval = that.dust_interval;
+ pits_interval = that.pits_interval;
+ scratch_lines = that.scratch_lines;
+ colorage = that.colorage;
+ scratch = that.scratch;
+ pits = that.pits;
+ dust = that.dust;
}
-int AgingMain::load_configuration()
+void AgingConfig::interpolate(AgingConfig &prev, AgingConfig &next,
+ int64_t prev_frame, int64_t next_frame, int64_t current_frame)
{
- return 0;
+ copy_from(prev);
}
+LOAD_CONFIGURATION_MACRO(AgingMain, AgingConfig)
void AgingMain::save_data(KeyFrame *keyframe)
{
+ FileXML output;
+// cause data to be stored directly in text
+ output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
+// Store data
+ output.tag.set_title("AGING");
+ output.tag.set_property("AREA_SCALE", config.area_scale);
+ output.tag.set_property("AGING_MODE", config.aging_mode);
+ output.tag.set_property("DUST_INTERVAL", config.dust_interval);
+ output.tag.set_property("PITS_INTERVAL", config.pits_interval);
+ output.tag.set_property("SCRATCH_LINES", config.scratch_lines);
+ output.tag.set_property("COLORAGE", config.colorage);
+ output.tag.set_property("SCRATCH", config.scratch);
+ output.tag.set_property("PITS", config.pits);
+ output.tag.set_property("DUST", config.dust);
+ output.append_tag();
+ output.tag.set_title("/AGING");
+ output.append_tag();
+ output.append_newline();
+ output.terminate_string();
}
void AgingMain::read_data(KeyFrame *keyframe)
{
+ FileXML input;
+ input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
+
+ int result = 0;
+
+ while( !(result = input.read_tag()) ) {
+ if( input.tag.title_is("AGING") ) {
+ config.area_scale = input.tag.get_property("AREA_SCALE", config.area_scale);
+ config.aging_mode = input.tag.get_property("AGING_MODE", config.aging_mode);
+ config.dust_interval = input.tag.get_property("DUST_INTERVAL", config.dust_interval);
+ config.pits_interval = input.tag.get_property("PITS_INTERVAL", config.pits_interval);
+ config.scratch_lines = input.tag.get_property("SCRATCH_LINES", config.scratch_lines);
+ config.colorage = input.tag.get_property("COLORAGE", config.colorage);
+ config.scratch = input.tag.get_property("SCRATCH", config.scratch);
+ config.pits = input.tag.get_property("PITS", config.pits);
+ config.dust = input.tag.get_property("DUST", config.dust);
+ }
+ }
}
+NEW_WINDOW_MACRO(AgingMain, AgingWindow)
+
int AgingMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
{
//printf("AgingMain::process_realtime 1\n");
this->input_ptr = input_ptr;
this->output_ptr = output_ptr;
-
- if(!aging_server) aging_server = new AgingServer(this,
- PluginClient::smp + 1,
- PluginClient::smp + 1);
+ int cpus = PluginClient::smp + 1;
+ if( cpus > 16 ) cpus = 16;
+ if( !aging_server )
+ aging_server = new AgingServer(this, cpus, cpus);
aging_server->process_packages();
//printf("AgingMain::process_realtime 2\n");
}
-
AgingServer::AgingServer(AgingMain *plugin, int total_clients, int total_packages)
: LoadServer(1, 1 /* total_clients, total_packages */)
{
return new AgingClient(this);
}
-
-
-
LoadPackage* AgingServer::new_package()
{
return new AgingPackage;
}
-
-
void AgingServer::init_packages()
{
- for(int i = 0; i < get_total_packages(); i++)
- {
+ for( int i = 0; i < get_total_packages(); i++ ) {
AgingPackage *package = (AgingPackage*)get_package(i);
package->row1 = plugin->input_ptr->get_h() * i / get_total_packages();
package->row2 = plugin->input_ptr->get_h() * (i + 1) / get_total_packages();
}
-
-
-
-
-
-
AgingClient::AgingClient(AgingServer *server)
: LoadClient(server)
{
this->plugin = server->plugin;
}
-
-
-
-
-
-
-
-
#define COLORAGE(type, components) \
{ \
int a, b; \
int i, j, k; \
\
- for(i = 0; i < h; i++) \
- { \
- for(j = 0; j < w; j++) \
- { \
- for(k = 0; k < 3; k++) \
- { \
- if(sizeof(type) == 4) \
- { \
+ for( i = 0; i < h; i++ ) { \
+ for( j = 0; j < w; j++ ) { \
+ for( k = 0; k < 3; k++ ) { \
+ if( sizeof(type) == 4 ) { \
a = (int)(((type**)input_rows)[i][j * components + k] * 0xffff); \
CLAMP(a, 0, 0xffff); \
} \
else \
a = (int)((type**)input_rows)[i][j * components + k]; \
- \
- if(sizeof(type) == 4) \
- { \
+ if( sizeof(type) == 4 ) { \
b = (a & 0xffff) >> 2; \
((type**)output_rows)[i][j * components + k] = \
(type)(a - b + 0x1800 + (EffectTV::fastrand() & 0x1000)) / 0xffff; \
} \
- else \
- if(sizeof(type) == 2) \
- { \
+ else if( sizeof(type) == 2 ) { \
b = (a & 0xffff) >> 2; \
((type**)output_rows)[i][j * components + k] = \
(type)(a - b + 0x1800 + (EffectTV::fastrand() & 0x1000)); \
} \
- else \
- { \
+ else { \
b = (a & 0xff) >> 2; \
((type**)output_rows)[i][j * components + k] = \
(type)(a - b + 0x18 + ((EffectTV::fastrand() >> 8) & 0x10)); \
} \
}
-void AgingClient::coloraging(unsigned char **output_rows,
- unsigned char **input_rows,
- int color_model,
- int w,
- int h)
+void AgingClient::coloraging(unsigned char **output_rows, unsigned char **input_rows,
+ int color_model, int w, int h)
{
- switch(color_model)
- {
- case BC_RGB888:
- case BC_YUV888:
- COLORAGE(uint8_t, 3);
- break;
-
- case BC_RGB_FLOAT:
- COLORAGE(float, 3);
- break;
-
- case BC_RGBA_FLOAT:
- COLORAGE(float, 4);
- break;
-
- case BC_RGBA8888:
- case BC_YUVA8888:
- COLORAGE(uint8_t, 4);
- break;
-
- case BC_RGB161616:
- case BC_YUV161616:
- COLORAGE(uint16_t, 3);
- break;
-
- case BC_RGBA16161616:
- case BC_YUVA16161616:
- COLORAGE(uint16_t, 4);
- break;
+ switch( color_model ) {
+ case BC_RGB888:
+ case BC_YUV888:
+ COLORAGE(uint8_t, 3);
+ break;
+
+ case BC_RGB_FLOAT:
+ COLORAGE(float, 3);
+ break;
+
+ case BC_RGBA_FLOAT:
+ COLORAGE(float, 4);
+ break;
+
+ case BC_RGBA8888:
+ case BC_YUVA8888:
+ COLORAGE(uint8_t, 4);
+ break;
+
+ case BC_RGB161616:
+ case BC_YUV161616:
+ COLORAGE(uint16_t, 3);
+ break;
+
+ case BC_RGBA16161616:
+ case BC_YUVA16161616:
+ COLORAGE(uint16_t, 4);
+ break;
}
}
-
-
-
-
-
#define SCRATCHES(type, components, chroma) \
{ \
int i, j, y, y1, y2; \
int a, b; \
int w_256 = w * 256; \
\
- for(i = 0; i < plugin->config.scratch_lines; i++) \
- { \
- if(plugin->config.scratches[i].life) \
- { \
- plugin->config.scratches[i].x = plugin->config.scratches[i].x + plugin->config.scratches[i].dx; \
- if(plugin->config.scratches[i].x < 0 || plugin->config.scratches[i].x > w_256) \
- { \
- plugin->config.scratches[i].life = 0; \
+ for( i = 0; i < plugin->config.scratch_lines; i++ ) { \
+ if( plugin->scratches[i].life ) { \
+ plugin->scratches[i].x = plugin->scratches[i].x + plugin->scratches[i].dx; \
+ if( plugin->scratches[i].x < 0 || plugin->scratches[i].x > w_256 ) { \
+ plugin->scratches[i].life = 0; \
break; \
} \
-\
- p = (type*)output_rows[0] + \
- (plugin->config.scratches[i].x >> 8) * \
- components; \
-\
- if(plugin->config.scratches[i].init) \
- { \
- y1 = plugin->config.scratches[i].init; \
- plugin->config.scratches[i].init = 0; \
- } \
- else \
- { \
+ p = (type*)output_rows[0] + (plugin->scratches[i].x >> 8) * components; \
+ if( plugin->scratches[i].init ) { \
+ y1 = plugin->scratches[i].init; \
+ plugin->scratches[i].init = 0; \
+ } \
+ else { \
y1 = 0; \
} \
\
- plugin->config.scratches[i].life--; \
- if(plugin->config.scratches[i].life) \
- { \
+ plugin->scratches[i].life--; \
+ if( plugin->scratches[i].life ) { \
y2 = h; \
} \
- else \
- { \
+ else { \
y2 = EffectTV::fastrand() % h; \
} \
\
- for(y = y1; y < y2; y++) \
- { \
- for(j = 0; j < (chroma ? 1 : 3); j++) \
- { \
- if(sizeof(type) == 4) \
- { \
+ for( y = y1; y < y2; y++ ) { \
+ for( j = 0; j < (chroma ? 1 : 3); j++ ) { \
+ if( sizeof(type) == 4 ) { \
int temp = (int)(p[j] * 0xffff); \
CLAMP(temp, 0, 0xffff); \
a = temp & 0xfeff; \
b = a & 0x10000; \
p[j] = (type)(a | (b - (b >> 8))) / 0xffff; \
} \
- else \
- if(sizeof(type) == 2) \
- { \
+ else if( sizeof(type) == 2 ) { \
int temp = (int)p[j]; \
a = temp & 0xfeff; \
a += 0x2000; \
b = a & 0x10000; \
p[j] = (type)(a | (b - (b >> 8))); \
} \
- else \
- { \
+ else { \
int temp = (int)p[j]; \
a = temp & 0xfe; \
a += 0x20; \
p[j] = (type)(a | (b - (b >> 8))); \
} \
} \
- \
- if(chroma) \
- { \
+ if( chroma ) { \
p[1] = chroma; \
p[2] = chroma; \
} \
p += w * components; \
} \
} \
- else \
- { \
- if((EffectTV::fastrand() & 0xf0000000) == 0) \
- { \
- plugin->config.scratches[i].life = 2 + (EffectTV::fastrand() >> 27); \
- plugin->config.scratches[i].x = EffectTV::fastrand() % (w_256); \
- plugin->config.scratches[i].dx = ((int)EffectTV::fastrand()) >> 23; \
- plugin->config.scratches[i].init = (EffectTV::fastrand() % (h - 1)) + 1; \
+ else { \
+ if( (EffectTV::fastrand() & 0xf0000000) == 0 ) { \
+ plugin->scratches[i].life = 2 + (EffectTV::fastrand() >> 27); \
+ plugin->scratches[i].x = EffectTV::fastrand() % (w_256); \
+ plugin->scratches[i].dx = ((int)EffectTV::fastrand()) >> 23; \
+ plugin->scratches[i].init = (EffectTV::fastrand() % (h - 1)) + 1; \
} \
} \
} \
}
-
void AgingClient::scratching(unsigned char **output_rows,
- int color_model,
- int w,
- int h)
+ int color_model, int w, int h)
{
- switch(color_model)
- {
- case BC_RGB888:
- SCRATCHES(uint8_t, 3, 0);
- break;
-
- case BC_RGB_FLOAT:
- SCRATCHES(float, 3, 0);
- break;
-
- case BC_YUV888:
- SCRATCHES(uint8_t, 3, 0x80);
- break;
-
- case BC_RGBA_FLOAT:
- SCRATCHES(float, 4, 0);
- break;
-
- case BC_RGBA8888:
- SCRATCHES(uint8_t, 4, 0);
- break;
-
- case BC_YUVA8888:
- SCRATCHES(uint8_t, 4, 0x80);
- break;
-
- case BC_RGB161616:
- SCRATCHES(uint16_t, 3, 0);
- break;
-
- case BC_YUV161616:
- SCRATCHES(uint16_t, 3, 0x8000);
- break;
-
- case BC_RGBA16161616:
- SCRATCHES(uint16_t, 4, 0);
- break;
-
- case BC_YUVA16161616:
- SCRATCHES(uint16_t, 4, 0x8000);
- break;
+ switch( color_model ) {
+ case BC_RGB888:
+ SCRATCHES(uint8_t, 3, 0);
+ break;
+
+ case BC_RGB_FLOAT:
+ SCRATCHES(float, 3, 0);
+ break;
+
+ case BC_YUV888:
+ SCRATCHES(uint8_t, 3, 0x80);
+ break;
+
+ case BC_RGBA_FLOAT:
+ SCRATCHES(float, 4, 0);
+ break;
+
+ case BC_RGBA8888:
+ SCRATCHES(uint8_t, 4, 0);
+ break;
+
+ case BC_YUVA8888:
+ SCRATCHES(uint8_t, 4, 0x80);
+ break;
+
+ case BC_RGB161616:
+ SCRATCHES(uint16_t, 3, 0);
+ break;
+
+ case BC_YUV161616:
+ SCRATCHES(uint16_t, 3, 0x8000);
+ break;
+
+ case BC_RGBA16161616:
+ SCRATCHES(uint16_t, 4, 0);
+ break;
+
+ case BC_YUVA16161616:
+ SCRATCHES(uint16_t, 4, 0x8000);
+ break;
}
}
-
#define PITS(type, components, luma, chroma) \
{ \
int i, j, k; \
int pnum, size, pnumscale; \
int x, y; \
- \
pnumscale = plugin->config.area_scale * 2; \
- \
- if(plugin->config.pits_interval) \
- { \
- pnum = pnumscale + (EffectTV::fastrand() % pnumscale); \
- plugin->config.pits_interval--; \
+ pnum = EffectTV::fastrand() % (plugin->config.pits_interval+1); \
+ if( plugin->pits_count ) { \
+ pnum += pnumscale; \
+ --plugin->pits_count; \
} \
- else \
- { \
- pnum = EffectTV::fastrand() % pnumscale; \
- if((EffectTV::fastrand() & 0xf8000000) == 0) \
- { \
- plugin->config.pits_interval = (EffectTV::fastrand() >> 28) + 20; \
+ else { \
+ if( (EffectTV::fastrand() & 0xf8000000) == 0 ) { \
+ plugin->pits_count = (EffectTV::fastrand() >> 28) + 20; \
} \
} \
- \
- for(i = 0; i < pnum; i++) \
- { \
+ for( i = 0; i < pnum; i++ ) { \
x = EffectTV::fastrand() % (w - 1); \
y = EffectTV::fastrand() % (h - 1); \
- \
size = EffectTV::fastrand() >> 28; \
- \
- for(j = 0; j < size; j++) \
- { \
+ for( j = 0; j < size; j++ ) { \
x = x + EffectTV::fastrand() % 3 - 1; \
y = y + EffectTV::fastrand() % 3 - 1; \
- \
CLAMP(x, 0, w - 1); \
CLAMP(y, 0, h - 1); \
- for(k = 0; k < (chroma ? 1 : 3); k++) \
- { \
+ for( k = 0; k < (chroma ? 1 : 3); k++ ) { \
((type**)output_rows)[y][x * components + k] = luma; \
} \
- \
- if(chroma) \
- { \
+ if( chroma ) { \
((type**)output_rows)[y][x * components + 1] = chroma; \
((type**)output_rows)[y][x * components + 2] = chroma; \
} \
- \
} \
} \
}
-
-
-
-
void AgingClient::pits(unsigned char **output_rows,
- int color_model,
- int w,
- int h)
+ int color_model, int w, int h)
{
- switch(color_model)
- {
+ switch( color_model ) {
case BC_RGB888:
PITS(uint8_t, 3, 0xc0, 0);
break;
int dnum; \
int d, len; \
int x, y; \
- \
- if(plugin->config.dust_interval == 0) \
- { \
- if((EffectTV::fastrand() & 0xf0000000) == 0) \
- { \
- plugin->config.dust_interval = EffectTV::fastrand() >> 29; \
+ if( plugin->dust_count == 0 ) { \
+ if( (EffectTV::fastrand() & 0xf0000000) == 0 ) { \
+ plugin->dust_count = EffectTV::fastrand() >> 29; \
} \
return; \
} \
- \
- dnum = plugin->config.area_scale * 4 + (EffectTV::fastrand() >> 27); \
- \
- for(i = 0; i < dnum; i++) \
- { \
+ dnum = plugin->config.area_scale * 4 + EffectTV::fastrand() % (plugin->config.dust_interval+1); \
+ for( i = 0; i < dnum; i++ ) { \
x = EffectTV::fastrand() % w; \
y = EffectTV::fastrand() % h; \
d = EffectTV::fastrand() >> 29; \
len = EffectTV::fastrand() % plugin->config.area_scale + 5; \
- \
- for(j = 0; j < len; j++) \
- { \
+ for( j = 0; j < len; j++ ) { \
CLAMP(x, 0, w - 1); \
CLAMP(y, 0, h - 1); \
- for(k = 0; k < (chroma ? 1 : 3); k++) \
- { \
+ for( k = 0; k < (chroma ? 1 : 3); k++ ) { \
((type**)output_rows)[y][x * components + k] = luma; \
} \
- \
- if(chroma) \
- { \
+ if( chroma ) { \
((type**)output_rows)[y][x * components + 1] = chroma; \
((type**)output_rows)[y][x * components + 2] = chroma; \
} \
- \
- y += AgingConfig::dy[d]; \
- x += AgingConfig::dx[d]; \
- \
- if(x < 0 || x >= w) break; \
- if(y < 0 || y >= h) break; \
- \
- \
+ y += AgingMain::dy[d]; \
+ x += AgingMain::dx[d]; \
+ if( x < 0 || x >= w ) break; \
+ if( y < 0 || y >= h ) break; \
d = (d + EffectTV::fastrand() % 3 - 1) & 7; \
} \
} \
- plugin->config.dust_interval--; \
+ --plugin->dust_count; \
}
-
-
void AgingClient::dusts(unsigned char **output_rows,
- int color_model,
- int w,
- int h)
+ int color_model, int w, int h)
{
- switch(color_model)
- {
- case BC_RGB888:
- DUSTS(uint8_t, 3, 0x10, 0);
- break;
-
- case BC_RGB_FLOAT:
- DUSTS(float, 3, (float)0x10 / 0xff, 0);
- break;
-
- case BC_YUV888:
- DUSTS(uint8_t, 3, 0x10, 0x80);
- break;
-
- case BC_RGBA_FLOAT:
- DUSTS(float, 4, (float)0x10 / 0xff, 0);
- break;
-
- case BC_RGBA8888:
- DUSTS(uint8_t, 4, 0x10, 0);
- break;
-
- case BC_YUVA8888:
- DUSTS(uint8_t, 4, 0x10, 0x80);
- break;
-
- case BC_RGB161616:
- DUSTS(uint16_t, 3, 0x1000, 0);
- break;
-
- case BC_YUV161616:
- DUSTS(uint16_t, 3, 0x1000, 0x8000);
- break;
-
- case BC_RGBA16161616:
- DUSTS(uint16_t, 4, 0x1000, 0);
- break;
-
- case BC_YUVA16161616:
- DUSTS(uint16_t, 4, 0x1000, 0x8000);
- break;
+ switch( color_model ) {
+ case BC_RGB888:
+ DUSTS(uint8_t, 3, 0x10, 0);
+ break;
+
+ case BC_RGB_FLOAT:
+ DUSTS(float, 3, (float)0x10 / 0xff, 0);
+ break;
+
+ case BC_YUV888:
+ DUSTS(uint8_t, 3, 0x10, 0x80);
+ break;
+
+ case BC_RGBA_FLOAT:
+ DUSTS(float, 4, (float)0x10 / 0xff, 0);
+ break;
+
+ case BC_RGBA8888:
+ DUSTS(uint8_t, 4, 0x10, 0);
+ break;
+
+ case BC_YUVA8888:
+ DUSTS(uint8_t, 4, 0x10, 0x80);
+ break;
+
+ case BC_RGB161616:
+ DUSTS(uint16_t, 3, 0x1000, 0);
+ break;
+
+ case BC_YUV161616:
+ DUSTS(uint16_t, 3, 0x1000, 0x8000);
+ break;
+
+ case BC_RGBA16161616:
+ DUSTS(uint16_t, 4, 0x1000, 0);
+ break;
+
+ case BC_YUVA16161616:
+ DUSTS(uint16_t, 4, 0x1000, 0x8000);
+ break;
}
}
-
void AgingClient::process_package(LoadPackage *package)
{
-//printf("AgingClient::process_package 1\n");
AgingPackage *local_package = (AgingPackage*)package;
unsigned char **input_rows = plugin->input_ptr->get_rows() + local_package->row1;
unsigned char **output_rows = plugin->output_ptr->get_rows() + local_package->row1;
-//printf("AgingClient::process_package 1\n");
- if(plugin->config.colorage)
+ if( plugin->config.colorage )
coloraging(output_rows,
input_rows,
plugin->input_ptr->get_color_model(),
plugin->input_ptr->get_w(),
local_package->row2 - local_package->row1);
-//printf("AgingClient::process_package 2\n");
- if(plugin->config.scratch)
+ if( plugin->config.scratch )
scratching(output_rows,
plugin->input_ptr->get_color_model(),
plugin->input_ptr->get_w(),
local_package->row2 - local_package->row1);
-//printf("AgingClient::process_package 3\n");
- if(plugin->config.pits)
+ if( plugin->config.pits )
pits(output_rows,
plugin->input_ptr->get_color_model(),
plugin->input_ptr->get_w(),
local_package->row2 - local_package->row1);
-//printf("AgingClient::process_package 4 %d\n", plugin->config.dust);
- if(plugin->config.dust)
+ if( plugin->config.dust )
dusts(output_rows,
plugin->input_ptr->get_color_model(),
plugin->input_ptr->get_w(),
local_package->row2 - local_package->row1);
-//printf("AgingClient::process_package 5\n");
}
-
-
AgingPackage::AgingPackage()
{
}
-
-
#define SCRATCH_MAX 20
-
-typedef struct _scratch
-{
- int life;
- int x;
- int dx;
- int init;
-} scratch_t;
-
class AgingConfig
{
public:
AgingConfig();
+ ~AgingConfig();
+
+ void reset();
+ int equivalent(AgingConfig &that);
+ void copy_from(AgingConfig &that);
+ void interpolate(AgingConfig &prev, AgingConfig &next,
+ int64_t prev_frame, int64_t next_frame, int64_t current_frame);
int area_scale;
int aging_mode;
- scratch_t scratches[SCRATCH_MAX];
-
- static int dx[8];
- static int dy[8];
int dust_interval;
-
-
int pits_interval;
-
int scratch_lines;
- int pit_count;
- int dust_count;
-
int colorage;
int scratch;
int pits;
public:
AgingClient(AgingServer *server);
- void coloraging(unsigned char **output_ptr,
- unsigned char **input_ptr,
- int color_model,
- int w,
- int h);
+ void coloraging(unsigned char **output_ptr, unsigned char **input_ptr,
+ int color_model, int w, int h);
void scratching(unsigned char **output_ptr,
- int color_model,
- int w,
- int h);
+ int color_model, int w, int h);
void pits(unsigned char **output_ptr,
- int color_model,
- int w,
- int h);
+ int color_model, int w, int h);
void dusts(unsigned char **output_ptr,
- int color_model,
- int w,
- int h);
+ int color_model, int w, int h);
void process_package(LoadPackage *package);
AgingMain *plugin;
};
+typedef struct _scratch {
+ int life;
+ int x;
+ int dx;
+ int init;
+} scratch_t;
+
class AgingMain : public PluginVClient
{
void save_data(KeyFrame *keyframe);
void read_data(KeyFrame *keyframe);
- int load_defaults();
- int save_defaults();
-
AgingServer *aging_server;
AgingClient *aging_client;
AgingEngine **engine;
VFrame *input_ptr, *output_ptr;
+
+ int pits_count, dust_count;
+ scratch_t scratches[SCRATCH_MAX];
+ static int dx[8], dy[8];
};
#include "agingwindow.h"
#include "language.h"
-
-
-
-
-
-
-
-AgingWindow::AgingWindow(AgingMain *client)
- : PluginClientWindow(client,
- 300,
- 170,
- 300,
- 170,
- 0)
+AgingWindow::AgingWindow(AgingMain *plugin)
+ : PluginClientWindow(plugin, 300, 180, 300, 180, 0)
{
- this->client = client;
+ this->plugin = plugin;
}
AgingWindow::~AgingWindow()
void AgingWindow::create_objects()
{
int x = 10, y = 10;
- add_subwindow(new BC_Title(x, y,
- "Film aging from EffectTV\n"
- "Copyright (C) 2001 FUKUCHI Kentarou")
- );
-//
-// y += 50;
-// add_subwindow(color = new AgingColor(x, y, client));
-//
-// y += 25;
-// add_subwindow(scratches = new AgingScratches(x, y, client));
-// add_subwindow(scratch_count = new AgingScratchCount(x + 100, y + 10, client));
-//
-// y += 25;
-// add_subwindow(pits = new AgingPits(x, y, client));
-// add_subwindow(pit_count = new AgingPitCount(x + 100, y + 10, client));
-//
-// y += 25;
-// add_subwindow(dust = new AgingDust(x, y, client));
-// add_subwindow(dust_count = new AgingDustCount(x + 100, y + 10, client));
-
- show_window();
- flush();
-}
-
-
-
-
-
-
-
-
-AgingColor::AgingColor(int x, int y, AgingMain *plugin)
- : BC_CheckBox(x, y, plugin->config.colorage, _("Grain"))
-{
- this->plugin = plugin;
-}
-
-int AgingColor::handle_event()
-{
- return 1;
-}
-
-
-
-
-
-AgingScratches::AgingScratches(int x, int y, AgingMain *plugin)
- : BC_CheckBox(x, y, plugin->config.scratch, _("Scratch"))
-{
- this->plugin = plugin;
-}
-
-int AgingScratches::handle_event()
-{
- return 1;
-}
-
-
-
-
-
-
-
+ BC_Title *title;
+ add_subwindow(title = new BC_Title(x, y, _("Aging:")));
+ y += title->get_h() + 15;
+ add_subwindow(color = new AgingCheckBox(this, x, y,
+ &plugin->config.colorage, _("Grain")));
+ y += color->get_h() + 5;
-AgingScratchCount::AgingScratchCount(int x, int y, AgingMain *plugin)
- : BC_ISlider(x,
- y,
- 0,
- 180,
- 180,
- 0,
- SCRATCH_MAX,
- plugin->config.scratch_lines)
-{
- this->plugin = plugin;
-}
-
-int AgingScratchCount::handle_event()
-{
- return 1;
-}
+ add_subwindow(scratches = new AgingCheckBox(this, x, y,
+ &plugin->config.scratch, _("Scratch")));
+ add_subwindow(scratch_count = new AgingISlider(this, x+100, y, 180,
+ 0,SCRATCH_MAX, &plugin->config.scratch_lines));
+ y += scratches->get_h() + 5;
+ add_subwindow(pits = new AgingCheckBox(this, x, y,
+ &plugin->config.pits, _("Pits")));
+ add_subwindow(pit_count = new AgingISlider(this, x+100, y, 180,
+ 0,100, &plugin->config.pits_interval));
+ y += pits->get_h() + 5;
+ add_subwindow(dust = new AgingCheckBox(this, x, y,
+ &plugin->config.dust, _("Dust")));
+ add_subwindow(dust_count = new AgingISlider(this, x+100, y, 180,
+ 0,100, &plugin->config.dust_interval));
-
-
-
-AgingPits::AgingPits(int x, int y, AgingMain *plugin)
- : BC_CheckBox(x, y, plugin->config.pits, _("Pits"))
-{
- this->plugin = plugin;
+ show_window(1);
}
-int AgingPits::handle_event()
-{
- return 1;
-}
-
-
-
-
-
-AgingPitCount::AgingPitCount(int x, int y, AgingMain *plugin)
- : BC_ISlider(x,
- y,
- 0,
- 180,
- 180,
- 0,
- 100,
- plugin->config.pit_count)
+AgingISlider::AgingISlider(AgingWindow *win,
+ int x, int y, int w, int min, int max, int *output)
+ : BC_ISlider(x, y, 0, w, w, min, max, *output)
{
- this->plugin = plugin;
+ this->win = win;
+ this->output = output;
}
-int AgingPitCount::handle_event()
+AgingISlider::~AgingISlider()
{
- return 1;
}
-
-
-
-
-
-
-
-
-AgingDust::AgingDust(int x, int y, AgingMain *plugin)
- : BC_CheckBox(x, y, plugin->config.dust, _("Dust"))
-{
- this->plugin = plugin;
-}
-
-int AgingDust::handle_event()
+int AgingISlider::handle_event()
{
- return 1;
+ int ret = BC_ISlider::handle_event();
+ win->plugin->send_configure_change();
+ return ret;
}
-
-
-
-
-AgingDustCount::AgingDustCount(int x, int y, AgingMain *plugin)
- : BC_ISlider(x,
- y,
- 0,
- 180,
- 180,
- 0,
- 100,
- plugin->config.dust_count)
+AgingCheckBox::AgingCheckBox(AgingWindow *win, int x, int y,
+ int *output, const char *text)
+ : BC_CheckBox(x, y, output, text)
{
- this->plugin = plugin;
+ this->win = win;
}
-int AgingDustCount::handle_event()
+int AgingCheckBox::handle_event()
{
- return 1;
+ int ret = BC_CheckBox::handle_event();
+ win->plugin->send_configure_change();
+ return ret;
}
-
-
-
-
-
#include "mutex.h"
#include "aging.h"
-
-class AgingColor;
-class AgingScratches;
-class AgingScratchCount;
-class AgingPits;
-class AgingPitCount;
-class AgingDust;
-class AgingDustCount;
+class AgingCheckBox;
+class AgingISlider;
class AgingWindow : public PluginClientWindow
{
public:
- AgingWindow(AgingMain *client);
+ AgingWindow(AgingMain *plugin);
~AgingWindow();
void create_objects();
-
- AgingMain *client;
-
-
- AgingColor *color;
- AgingScratches *scratches;
- AgingScratchCount *scratch_count;
- AgingPits *pits;
- AgingPitCount *pit_count;
- AgingDust *dust;
- AgingDustCount *dust_count;
-};
-
-
-
-
-
-class AgingColor : public BC_CheckBox
-{
-public:
- AgingColor(int x, int y, AgingMain *plugin);
- int handle_event();
AgingMain *plugin;
-};
-
-class AgingScratches : public BC_CheckBox
-{
-public:
- AgingScratches(int x, int y, AgingMain *plugin);
- int handle_event();
- AgingMain *plugin;
+ AgingCheckBox *color;
+ AgingCheckBox *scratches;
+ AgingISlider *scratch_count;
+ AgingCheckBox *pits;
+ AgingISlider *pit_count;
+ AgingCheckBox *dust;
+ AgingISlider *dust_count;
};
-
-class AgingScratchCount : public BC_ISlider
+class AgingISlider : public BC_ISlider
{
public:
- AgingScratchCount(int x, int y, AgingMain *plugin);
+ AgingISlider(AgingWindow *win,
+ int x, int y, int w, int min, int max, int *output);
+ ~AgingISlider();
int handle_event();
- AgingMain *plugin;
-};
-class AgingPits : public BC_CheckBox
-{
-public:
- AgingPits(int x, int y, AgingMain *plugin);
- int handle_event();
- AgingMain *plugin;
+ AgingWindow *win;
+ int *output;
};
-class AgingPitCount : public BC_ISlider
+class AgingCheckBox : public BC_CheckBox
{
public:
- AgingPitCount(int x, int y, AgingMain *plugin);
+ AgingCheckBox(AgingWindow *win, int x, int y, int *output, const char *text);
int handle_event();
- AgingMain *plugin;
-};
-
-
-
-
-
-
-
-class AgingDust : public BC_CheckBox
-{
-public:
- AgingDust(int x, int y, AgingMain *plugin);
- int handle_event();
- AgingMain *plugin;
+ AgingWindow *win;
};
-class AgingDustCount : public BC_ISlider
-{
-public:
- AgingDustCount(int x, int y, AgingMain *plugin);
- int handle_event();
- AgingMain *plugin;
-};
-
-
-
-
-
-
-
#endif
This plugin removes vertical scratches from digitized films.
Reworked for cin5 by GG. 03/2018, from the laws of Fizick's
+Adapted strategy to mark, test, draw during port.
*/
#include "language.h"
#include "descratch.h"
+#include <math.h>
+
REGISTER_PLUGIN(DeScratchMain)
DeScratchMain::DeScratchMain(PluginServer *server)
{
inf = 0; sz_inf = 0;
src = 0; dst = 0;
- tmp_frame = 0;
- blurry = 0;
+ tmpy = 0; blury = 0;
overlay_frame = 0;
}
delete [] inf;
delete src;
delete dst;
- delete blurry;
- delete tmp_frame;
+ delete blury;
+ delete tmpy;
delete overlay_frame;
}
void DeScratchConfig::reset()
{
- threshold = 24;
- asymmetry = 16;
+ threshold = 12;
+ asymmetry = 25;
min_width = 1;
- max_width = 3;
- min_len = 1;
+ max_width = 2;
+ min_len = 10;
max_len = 100;
- max_angle = 45;
- blur_len = 4;
- gap_len = 10;
+ max_angle = 5;
+ blur_len = 2;
+ gap_len = 0;
mode_y = MODE_ALL;
mode_u = MODE_NONE;
mode_v = MODE_NONE;
mark = 0;
ffade = 100;
border = 2;
+ edge_only = 0;
}
DeScratchConfig::DeScratchConfig()
mode_v == that.mode_v &&
mark == that.mark &&
ffade == that.ffade &&
- border == that.border;
+ border == that.border &&
+ edge_only == that.edge_only;
}
void DeScratchConfig::copy_from(DeScratchConfig &that)
{
mark = that.mark;
ffade = that.ffade;
border = that.border;
+ edge_only = that.edge_only;
}
void DeScratchConfig::interpolate(DeScratchConfig &prev, DeScratchConfig &next,
output.tag.set_property("MARK", config.mark);
output.tag.set_property("FFADE", config.ffade);
output.tag.set_property("BORDER", config.border);
+ output.tag.set_property("EDGE_ONLY", config.edge_only);
output.append_tag();
output.tag.set_title("/DESCRATCH");
output.append_tag();
while( !(result = input.read_tag()) ) {
if(input.tag.title_is("DESCRATCH")) {
config.threshold = input.tag.get_property("THRESHOLD", config.threshold);
- config.asymmetry = input.tag.get_property("ASYMMETRY", config.asymmetry);
+ config.asymmetry = input.tag.get_property("ASYMMETRY", config.asymmetry);
config.min_width = input.tag.get_property("MIN_WIDTH", config.min_width);
config.max_width = input.tag.get_property("MAX_WIDTH", config.max_width);
config.min_len = input.tag.get_property("MIN_LEN", config.min_len);
config.mark = input.tag.get_property("MARK", config.mark);
config.ffade = input.tag.get_property("FFADE", config.ffade);
config.border = input.tag.get_property("BORDER", config.border);
+ config.edge_only = input.tag.get_property("EDGE_ONLY", config.edge_only);
}
}
}
-void DeScratchMain::get_extrems_plane(int comp, int thresh)
-{
- uint8_t **rows = blurry->get_rows();
- int d = config.max_width, d1 = d+1, wd = src_w - d1;
- int bpp = 3, dsz = d * bpp;
- int asym = config.asymmetry;
- if( thresh > 0 ) { // black (low value) scratches
- for( int y=0; y<src_h; ++y ) {
- uint8_t *ip = inf + y*src_w;
- int x = 0;
- for( ; x<d1; ++x ) *ip++ = SD_NULL;
- uint8_t *dp = rows[y] + x*bpp + comp;
- for( ; x<wd; ++x,dp+=bpp ) {
- uint8_t *lp = dp-dsz, *rp = dp+dsz;
- *ip++ = (lp[0]-*dp) > thresh && (rp[0]-*dp) > thresh &&
- (abs(lp[-bpp]-rp[+bpp]) <= asym) &&
- ((lp[0]-lp[+bpp]) + (rp[0]-rp[-bpp]) >
- (lp[-bpp]-lp[0]) + (rp[bpp]-rp[0])) ?
- SD_EXTREM : SD_NULL; // sharp extremum found
- }
- for( ; x<src_w; ++x ) *ip++ = SD_NULL;
- }
- }
- else { // white (high value) scratches
- for( int y=0; y<src_h; ++y ) {
- uint8_t *ip = inf + y*src_w;
- int x = 0;
- for( ; x<d1; ++x ) *ip++ = SD_NULL;
- uint8_t *dp = rows[y] + x*bpp + comp;
- for( ; x<wd; ++x,dp+=bpp ) {
- uint8_t *lp = dp-dsz, *rp = dp+dsz;
- *ip++ = (lp[0]-*dp) < thresh && (rp[0]-*dp) < thresh &&
- (abs(lp[-bpp]-rp[+bpp]) <= asym) &&
- ((lp[0]-lp[+bpp]) + (rp[0]-rp[-bpp]) <
- (lp[-bpp]-lp[0]) + (rp[bpp]-rp[0])) ?
- SD_EXTREM : SD_NULL; // sharp extremum found
- }
- for( ; x<src_w; ++x ) *ip++ = SD_NULL;
- }
- }
-}
-
-//
-void DeScratchMain::remove_min_extrems_plane(int comp, int thresh)
+void DeScratchMain::set_extrems_plane(int width, int comp, int thresh)
{
- uint8_t **rows = blurry->get_rows();
- int d = config.min_width, d1 = d+1, wd = src_w - d1;
- int bpp = 3, dsz = d * bpp;
- int asym = config.asymmetry;
+ uint8_t **rows = blury->get_rows();
+ int r = width, r1 = r+1, wd = src_w - r1;
+ int bpp = 3, dsz = r * bpp;
+ int asym = config.asymmetry * 256 / 100;
if( thresh > 0 ) { // black (low value) scratches
for( int y=0; y<src_h; ++y ) {
- uint8_t *ip = inf + y*src_w;
- uint8_t *dp = rows[y] + d1*bpp + comp;
- for( int x=d1; x<wd; ++x,++ip,dp+=bpp ) {
- if( *ip != SD_EXTREM ) continue;
+ uint8_t *ip = inf + y*src_w + r1;
+ uint8_t *dp = rows[y] + r1*bpp + comp;
+ for( int x=r1; x<wd; ++x,++ip,dp+=bpp ) {
+ if( *ip != SD_NULL ) continue;
uint8_t *lp = dp-dsz, *rp = dp+dsz;
if( (lp[0]-*dp) > thresh && (rp[0]-*dp) > thresh &&
- (abs(lp[-bpp]-rp[+bpp]) <= asym) &&
- ((lp[0]-lp[+bpp]) + (rp[0]-rp[-bpp]) >
- (lp[-bpp]-lp[0]) + (rp[bpp]-rp[0])) )
- *ip = SD_NULL; // sharp extremum found
+ (abs(lp[-bpp]-rp[+bpp]) <= asym) &&
+ ((lp[0]-lp[+bpp]) + (rp[0]-rp[-bpp]) >
+ (lp[-bpp]-lp[0]) + (rp[bpp]-rp[0])) ) {
+ *ip = SD_EXTREM;
+ for( int i=1; i<r; ++i ) ip[i] = ip[-i] = SD_EXTREM;
+ }
}
}
}
else { // white (high value) scratches
for( int y=0; y<src_h; ++y ) {
- uint8_t *ip = inf + y*src_w;
- uint8_t *dp = rows[y] + d1*bpp + comp;
- for( int x=d1; x<wd; ++x,++ip,dp+=bpp ) {
- if( *ip != SD_EXTREM ) continue;
+ uint8_t *ip = inf + y*src_w + r1;
+ uint8_t *dp = rows[y] + r1*bpp + comp;
+ for( int x=r1; x<wd; ++x,++ip,dp+=bpp ) {
+ if( *ip != SD_NULL ) continue;
uint8_t *lp = dp-dsz, *rp = dp+dsz;
if( (lp[0]-*dp) < thresh && (rp[0]-*dp) < thresh &&
- (abs(lp[-bpp]-rp[+bpp]) <= asym) &&
- ((lp[0]-lp[+bpp]) + (rp[0]-rp[-bpp]) <
- (lp[-bpp]-lp[0]) + (rp[bpp]-rp[0])) )
- *ip = SD_NULL; // sharp extremum found
+ (abs(lp[-bpp]-rp[+bpp]) <= asym) &&
+ ((lp[0]-lp[+bpp]) + (rp[0]-rp[-bpp]) <
+ (lp[-bpp]-lp[0]) + (rp[bpp]-rp[0])) ) {
+ *ip = SD_EXTREM;
+ for( int i=1; i<r; ++i ) ip[i] = ip[-i] = SD_EXTREM;
+ }
}
}
}
}
+//
void DeScratchMain::close_gaps()
{
int len = config.gap_len * src_h / 100;
- for( int y=len; y<src_h; ++y ) {
+ for( int y=0; y<src_h; ++y ) {
uint8_t *ip = inf + y*src_w;
for( int x=0; x<src_w; ++x,++ip ) {
- if( *ip != SD_EXTREM ) continue;
- uint8_t *bp = ip; // expand to previous lines in range
- for( int i=len; --i>0; ) *(bp-=src_w) = SD_EXTREM;
+ if( !(*ip & SD_EXTREM) ) continue;
+ uint8_t *bp = ip, b = *bp; // expand to previous lines in range
+ int i = len < y ? len : y;
+ while( --i>=0 ) *(bp-=src_w) = b;
}
}
}
int w2 = src_w - 2;
int min_len = config.min_len * src_h / 100;
int max_len = config.max_len * src_h / 100;
- int maxwidth = config.max_width*2 + 1;
- int maxangle = config.max_angle;
+ int maxwidth = config.max_width;
+ float sin_mxa = sin(config.max_angle * M_PI/180.);
for( int y=0; y<src_h; ++y ) {
for( int x=2; x<w2; ++x ) {
- int ofs = y*src_w + x; // offset of first candidate
- if( inf[ofs] != SD_EXTREM ) continue;
- int ctr = ofs+1, nctr = ctr; // centered to inf for maxwidth=3
+ int ofs = y*src_w + x; // first candidate
+ if( !(inf[ofs] & SD_EXTREM) ) continue;
+ int ctr = ofs, nctr = ctr;
int hy = src_h - y, len;
- for( len=0; len<hy; ++len ) { // cycle along inf
+ for( len=0; len<hy; ++len ) { // check vertical aspect
uint8_t *ip = inf + ctr;
int n = 0; // number good points in row
- if( maxwidth >= 3 ) {
- if( ip[-2] == SD_EXTREM ) { ip[-2] = SD_TESTED; nctr = ctr-2; ++n; }
- if( ip[+2] == SD_EXTREM ) { ip[+2] = SD_TESTED; nctr = ctr+2; ++n; }
- }
- if( ip[-1] == SD_EXTREM ) { ip[-1] = SD_TESTED; nctr = ctr-1; ++n; }
- if( ip[+1] == SD_EXTREM ) { ip[+1] = SD_TESTED; nctr = ctr+1; ++n; }
- if( ip[+0] == SD_EXTREM ) { ip[+0] = SD_TESTED; nctr = ctr+0; ++n; }
- // end of points tests, check result for row:
- // check gap and angle, if no points or big angle, it is end of inf
- if( !n || abs(nctr%src_w - x) >= maxwidth+len*maxangle/57 ) break;
- ctr = nctr + src_w; // new center for next row test
+ if( ip[-1] & SD_EXTREM ) { ip[-1] |= SD_TESTED; nctr = ctr-1; ++n; }
+ if( ip[+1] & SD_EXTREM ) { ip[+1] |= SD_TESTED; nctr = ctr+1; ++n; }
+ if( ip[+0] & SD_EXTREM ) { ip[+0] |= SD_TESTED; nctr = ctr+0; ++n; }
+ if( !n ) break;
+ ctr = nctr + src_w; // new center for next row test
}
- int mask = len >= min_len && len <= max_len ? SD_GOOD : SD_REJECT;
- ctr = ofs+1; nctr = ctr; // pass2
+ int v = (!config.edge_only || y == 0 || y+len>=src_h) &&
+ abs(nctr%src_w - x) < maxwidth + len*sin_mxa &&
+ len >= min_len && len <= max_len ? SD_GOOD : SD_REJECT;
+ ctr = ofs; nctr = ctr; // pass2
for( len=0; len<hy; ++len ) { // cycle along inf
uint8_t *ip = inf + ctr;
int n = 0; // number good points in row
- if( maxwidth >= 3 ) {
- if( ip[-2] == SD_TESTED ) { ip[-2] = mask; nctr = ctr-2; ++n; }
- if( ip[+2] == SD_TESTED ) { ip[+2] = mask; nctr = ctr+2; ++n; }
- }
- if( ip[-1] == SD_TESTED ) { ip[-1] = mask; nctr = ctr-1; ++n; }
- if( ip[+1] == SD_TESTED ) { ip[+1] = mask; nctr = ctr+1; ++n; }
- if( ip[+0] == SD_TESTED ) { ip[+0] = mask; nctr = ctr+0; ++n; }
- // end of points tests, check result for row:
- // check gap and angle, if no points or big angle, it is end of inf
- if( !n || abs(nctr%src_w - x) >= maxwidth+len*maxangle/57 ) break;
- ctr = nctr + src_w; // new center for next row test
+ if( ip[-1] & SD_TESTED ) { ip[-1] = v; nctr = ctr-1; ++n; }
+ if( ip[+1] & SD_TESTED ) { ip[+1] = v; nctr = ctr+1; ++n; }
+ if( ip[+0] & SD_TESTED ) { ip[+0] = v; nctr = ctr+0; ++n; }
+ if( !n ) break;
+ ctr = nctr + src_w; // new center for next row test
}
}
}
}
-void DeScratchMain::mark_scratches_plane(int comp, int mask, int value)
+void DeScratchMain::mark_scratches_plane()
{
int bpp = 3, dst_w = dst->get_w(), dst_h = dst->get_h();
uint8_t **rows = dst->get_rows();
for( int y=0; y<dst_h; ++y ) {
- uint8_t *dp = rows[y] + comp;
uint8_t *ip = inf + y*src_w;
- for( int x=0; x<dst_w; ++x,++ip,dp+=bpp ) {
- if( *ip == mask ) *dp = value;
+ for( int x=0; x<dst_w; ++x,++ip ) {
+ if( *ip == SD_NULL ) continue;
+ static uint8_t grn_yuv[3] = { 0xad, 0x28, 0x19, };
+ static uint8_t ylw_yuv[3] = { 0xdb, 0x0f, 0x89, };
+ static uint8_t red_yuv[3] = { 0x40, 0x66, 0xef, };
+ for( int comp=0; comp<3; ++comp ) {
+ uint8_t *dp = rows[y] + comp + x*bpp;
+ if( *ip & SD_GOOD )
+ *dp = config.threshold > 0 ? grn_yuv[comp] : red_yuv[comp];
+ else if( *ip & SD_REJECT )
+ *dp = ylw_yuv[comp];
+ }
}
}
}
void DeScratchMain::remove_scratches_plane(int comp)
{
- int r = config.max_width;
- int fade = (config.ffade * 1024) / 100; // norm 2^10
- int fade1 = 1024 - fade;
+ int bpp = 3, w1 = src_w-1;
+ int border = config.border;
uint8_t *ip = inf;
- uint8_t **src_rows = src->get_rows();
uint8_t **dst_rows = dst->get_rows();
- uint8_t **blur_rows = blurry->get_rows();
- int bpp = 3, margin = r+config.border+2, wm = src_w-margin;
- float nrm = 1. / 1024.f, nrm2r = nrm / (2*r*bpp);
+ uint8_t **blur_rows = blury->get_rows();
+ float a = config.ffade / 100, b = 1 - a;
for( int y=0; y<src_h; ++y ) {
- int left = 0;
- uint8_t *inp = src_rows[y] + comp;
+ int left = -1;
uint8_t *out = dst_rows[y] + comp;
uint8_t *blur = blur_rows[y] + comp;
- for( int x=margin; x<wm; ++x ) {
+ for( int x=1; x<w1; ++x ) {
uint8_t *dp = ip + x;
- if( (dp[+0]&SD_GOOD) && !(dp[-1]&SD_GOOD) ) left = x;
- if( left!=0 && (dp[+0]&SD_GOOD) && !(dp[+1]&SD_GOOD) ) { // the inf, left/right
- int right = x;
- int ctr = (left + right) / 2; // the inf center
- int ls = ctr - r, rs = ctr + r;
- int lt = ls - config.border - 1, rt = rs + config.border + 1;
- lt *= bpp; ls *= bpp; rs *= bpp; rt *= bpp; // component index
- for( int i=ls; i<=rs; i+=bpp ) { // across the inf
- int lv = inp[i] + blur[lt] - blur[i];
- int rv = inp[i] + blur[rt] - blur[i];
- lv = fade*lv + fade1*inp[lt];
- rv = fade*rv + fade1*inp[rt];
- int v = nrm2r*(lv*(rs-i) + rv*(i-ls));
- out[i] = CLIP(v,0,255);
- }
- for( int i=lt; i<ls; i+=bpp ) { // at left border
- int lv = inp[i] + blur[lt] - blur[i];
- int v = nrm*(fade*lv + fade1*inp[lt]);
- out[i] = CLIP(v,0,255);
- }
- for( int i=rt; i>rs; i-=bpp ) { // at right border
- int rv = inp[i] + blur[rt] - blur[i];
- int v = nrm*(fade*rv + fade1*inp[rt]);
- out[i] = CLIP(v,0,255);
- }
- left = 0;
+ if( !(dp[-1]&SD_GOOD) && (dp[0]&SD_GOOD) ) left = x;
+ if( left < 0 || !(dp[0]&SD_GOOD) || (dp[1]&SD_GOOD) ) continue;
+ int right = x;
+ int ctr = (left + right) / 2; // scratch center
+ int r = (right - left + border) / 2 + 1;
+ left = 0;
+ int ls = ctr - r, rs = ctr + r; // scratch edges
+ int lt = ls - border, rt = rs + border; // border edges
+ if( ls < 0 ) ls = 0;
+ if( rs > w1 ) rs = w1;
+ if( lt < 0 ) lt = 0;
+ if( rt > w1 ) rt = w1;
+ ls *= bpp; rs *= bpp;
+ lt *= bpp; rt *= bpp;
+ if( rs > ls ) {
+ float s = 1. / (rs - ls);
+ for( int i=ls; (i+=bpp)<rs; ) { // across the scratch
+ int lv = a * blur[ls] + b * out[i];
+ int rv = a * blur[rs] + b * out[i];
+ int v = s * (lv*(rs-i) + rv*(i-ls));
+ out[i] = CLIP(v, 0, 255);
+ }
+ }
+ if( !border ) continue;
+ if( ls > lt ) {
+ float s = 1. / (ls - lt);
+ for( int i=lt; (i+=bpp)<=ls; ) { // at left border
+ int lv = a * out[lt] + b * out[i];
+ int rv = a * blur[i] + b * out[i];
+ int v = s * (lv*(ls-i) + rv*(i-lt));
+ out[i] = CLIP(v, 0, 255);
+ }
+ }
+ if( rt > rs ) {
+ float s = 1. / (rt - rs);
+ for( int i=rt; (i-=bpp)>=rs; ) { // at right border
+ int lv = a * blur[i] + b * out[i];
+ int rv = a * out[rt] + b * out[i];
+ int v = s * (rv*(i-rs) + lv*(rt-i));
+ out[i] = CLIP(v, 0, 255);
+ }
}
}
ip += src_w;
}
}
-void DeScratchMain::pass(int comp, int thresh)
-{
-// pass for current plane and current sign
- get_extrems_plane(comp, thresh);
- if( config.min_width > 1 )
- remove_min_extrems_plane(comp, thresh);
- close_gaps();
- test_scratches();
- if( config.mark ) {
- int value = config.threshold > 0 ? 0 : 255;
- mark_scratches_plane(comp, SD_GOOD, value);
- mark_scratches_plane(comp, SD_REJECT, 127);
- }
- else
- remove_scratches_plane(comp);
-}
-
void DeScratchMain::blur(int scale)
{
- int tw = src_w, th = (src_h / scale) & ~1;
- if( tmp_frame &&
- (tmp_frame->get_w() != tw || tmp_frame->get_h() != th) ) {
- delete tmp_frame; tmp_frame = 0;
+ int th = (src_h / scale) & ~1;
+ if( tmpy&& (tmpy->get_w() != src_w || tmpy->get_h() != th) ) {
+ delete tmpy; tmpy= 0;
}
- if( !tmp_frame )
- tmp_frame = new VFrame(tw, th, BC_YUV888);
-
- if( blurry &&
- (blurry->get_w() != src_w || blurry->get_h() != src_h) ) {
- delete blurry; blurry = 0;
+ if( !tmpy ) tmpy = new VFrame(src_w, th, BC_YUV888);
+ if( blury && (blury->get_w() != src_w || blury->get_h() != src_h) ) {
+ delete blury; blury= 0;
}
- if( !blurry )
- blurry = new VFrame(src_w, src_h, BC_YUV888);
-
- overlay_frame->overlay(tmp_frame, src,
- 0,0,src_w,src_h, 0,0,tw,th, 1.f, TRANSFER_NORMAL, LINEAR_LINEAR);
- overlay_frame->overlay(blurry, tmp_frame,
- 0,0,tw,th, 0,0,src_w,src_h, 1.f, TRANSFER_NORMAL, CUBIC_CUBIC);
+ if( !blury ) blury = new VFrame(src_w, src_h, BC_YUV888);
+ overlay_frame->overlay(tmpy, src,
+ 0,0,src_w,src_h, 0,0,src_w,th, 1.f, TRANSFER_NORMAL, LINEAR_LINEAR);
+ overlay_frame->overlay(blury, tmpy,
+ 0,0,src_w,th, 0,0,src_w,src_h, 1.f, TRANSFER_NORMAL, CUBIC_CUBIC);
}
void DeScratchMain::copy(int comp)
}
}
+void DeScratchMain::pass(int comp, int thresh)
+{
+// pass for current plane and current sign
+ int w0 = config.min_width, w1 = config.max_width;
+ if( w1 < w0 ) w1 = w0;
+ for( int iw=w0; iw<=w1; ++iw )
+ set_extrems_plane(iw, comp, thresh);
+}
+
void DeScratchMain::plane_pass(int comp, int mode)
{
int threshold = config.threshold;
}
}
+void DeScratchMain::plane_proc(int comp, int mode)
+{
+ if( mode == MODE_NONE ) return;
+ remove_scratches_plane(comp);
+}
+
int DeScratchMain::process_realtime(VFrame *input, VFrame *output)
{
load_configuration();
if( sz_inf != sz ) { delete [] inf; inf = 0; }
if( !inf ) inf = new uint8_t[sz_inf=sz];
blur(config.blur_len + 1);
+ memset(inf, SD_NULL, sz_inf);
plane_pass(0, config.mode_y);
plane_pass(1, config.mode_u);
plane_pass(2, config.mode_v);
+ close_gaps();
+ test_scratches();
+ if( !config.mark ) {
+ plane_proc(0, config.mode_y);
+ plane_proc(1, config.mode_u);
+ plane_proc(2, config.mode_v);
+ }
+ else
+ mark_scratches_plane();
output->transfer_from(dst);
}
return 0;
add_tool(threshold = new DeScratchISlider(this, x1, y, x2-x1-10, 0,64, &config.threshold));
add_tool(title = new BC_Title(x1=x2, y, _("asymmetry:")));
x1 += title->get_w()+16;
- add_tool(asymmetry = new DeScratchISlider(this, x1, y, get_w()-x1-15, 0,64, &config.asymmetry));
+ add_tool(asymmetry = new DeScratchFSlider(this, x1, y, get_w()-x1-15, 0,100., &config.asymmetry));
y += threshold->get_h() + 10;
add_tool(title = new BC_Title(x1=x, y, _("Mode:")));
w1 = title->get_w()+16; x1 += w1;
add_tool(title = new BC_Title(x1, y, _("min:")));
x1 += title->get_w()+16;
- add_tool(min_width = new DeScratchISlider(this, x1, y, x2-x1-10, 0,16, &config.min_width));
+ add_tool(min_width = new DeScratchISlider(this, x1, y, x2-x1-10, 1,16, &config.min_width));
add_tool(title = new BC_Title(x1=x2, y, _("max:")));
x1 += title->get_w()+16;
- add_tool(max_width = new DeScratchISlider(this, x1, y, get_w()-x1-15, 0,16, &config.max_width));
+ add_tool(max_width = new DeScratchISlider(this, x1, y, get_w()-x1-15, 1,16, &config.max_width));
y += min_width->get_h() + 10;
add_tool(title = new BC_Title(x1=x, y, _("len:")));
w1 = title->get_w()+16; x1 += w1;
add_tool(title = new BC_Title(x1, y, _("blur:")));
x1 += title->get_w()+16;
- add_tool(blur_len = new DeScratchISlider(this, x1, y, x2-x1-10, 0,16, &config.blur_len));
+ add_tool(blur_len = new DeScratchISlider(this, x1, y, x2-x1-10, 0,8, &config.blur_len));
add_tool(title = new BC_Title(x1=x2, y, _("gap:")));
x1 += title->get_w()+16;
add_tool(gap_len = new DeScratchFSlider(this, x1, y, get_w()-x1-15, 0.0,100.0, &config.gap_len));
add_tool(title = new BC_Title(x1=x, y, _("max angle:")));
w1 = title->get_w()+16; x1 += w1;
- add_tool(max_angle = new DeScratchFSlider(this, x1, y, x2-x1-10, 0.0,90.0, &config.max_angle));
+ add_tool(max_angle = new DeScratchFSlider(this, x1, y, x2-x1-10, 0.0,15.0, &config.max_angle));
add_tool(title = new BC_Title(x1=x2, y, _("fade:")));
x1 += title->get_w()+16;
add_tool(ffade = new DeScratchFSlider(this, x1, y, get_w()-x1-15, 0.0,100.0, &config.ffade));
x1 += title->get_w()+16;
add_tool(border = new DeScratchISlider(this, x1, y, x2-x1-10, 0,16, &config.border));
add_tool(mark = new DeScratchMark(this, x1=x2, y));
+ x1 += mark->get_w() + 10;
+ add_tool(edge_only = new DeScratchEdgeOnly(this, x1, y));
+
w1 = DeScratchReset::calculate_w(this, _("Reset"));
- add_tool(reset = new DeScratchReset(this, get_w()-w1-15, y));
+ int h1 = DeScratchReset::calculate_h();
+ add_tool(reset = new DeScratchReset(this, get_w()-w1-15, get_h()-h1-15));
show_window();
}
void DeScratchWindow::update_gui()
{
DeScratchConfig &config = plugin->config;
- y_mode->update(config.mode_y);
- u_mode->update(config.mode_u);
- v_mode->update(config.mode_v);
+ threshold->update(config.threshold);
+ asymmetry->update(config.asymmetry);
min_width->update(config.min_width);
max_width->update(config.max_width);
min_len->update(config.min_len);
max_len->update(config.max_len);
+ max_angle->update(config.max_angle);
blur_len->update(config.blur_len);
gap_len->update(config.gap_len);
- max_angle->update(config.max_angle);
- ffade->update(config.ffade);
+ y_mode->update(config.mode_y);
+ u_mode->update(config.mode_u);
+ v_mode->update(config.mode_v);
mark->update(config.mark);
+ ffade->update(config.ffade);
+ border->update(config.border);
+ edge_only->update(config.edge_only);
}
return ret;
}
+DeScratchEdgeOnly::DeScratchEdgeOnly(DeScratchWindow *win, int x, int y)
+ : BC_CheckBox(x, y, &win->plugin->config.edge_only, _("Edge"))
+{
+ this->win = win;
+};
+
+DeScratchEdgeOnly::~DeScratchEdgeOnly()
+{
+}
+
+int DeScratchEdgeOnly::handle_event()
+{
+ int ret = BC_CheckBox::handle_event();
+ win->plugin->send_configure_change();
+ return ret;
+}
+
DeScratchReset::DeScratchReset(DeScratchWindow *win, int x, int y)
: BC_GenericButton(x, y, _("Reset"))
{
// so that write_pgm can create grey images of inf
#define SD_NULL 0
#define SD_EXTREM 0x80
-#define SD_TESTED 0x60
-#define SD_GOOD 0x40
+#define SD_TESTED 0x40
+#define SD_GOOD 0x20
#define SD_REJECT 0x10
#define MODE_NONE 0
class DeScratchISlider;
class DeScratchFSlider;
class DeScratchMark;
+class DeScratchEdgeOnly;
class DeScratchReset;
int64_t prev_frame, int64_t next_frame, int64_t current_frame);
int threshold;
- int asymmetry;
+ float asymmetry;
int min_width;
int max_width;
float min_len;
int mark;
float ffade;
int border;
+ int edge_only;
};
class DeScratchMain : public PluginVClient
uint8_t *inf; int sz_inf;
int src_w, src_h;
VFrame *src, *dst;
- VFrame *tmp_frame, *blurry;
+ VFrame *tmpy, *blury;
OverlayFrame *overlay_frame;
int is_realtime();
void update_gui();
void save_data(KeyFrame *keyframe);
void read_data(KeyFrame *keyframe);
- void get_extrems_plane(int comp, int thresh);
- void remove_min_extrems_plane(int comp, int thresh);
+ void set_extrems_plane(int width, int comp, int thresh);
void close_gaps();
void test_scratches();
- void mark_scratches_plane(int comp, int mask, int value);
+ void mark_scratches_plane();
void remove_scratches_plane(int comp);
- void pass(int comp, int thresh);
void blur(int scale);
void copy(int comp);
+ void pass(int comp, int thresh);
void plane_pass(int comp, int mode);
+ void plane_proc(int comp, int mode);
int process_realtime(VFrame *input, VFrame *output);
};
DeScratchMain *plugin;
DeScratchMode *y_mode, *u_mode, *v_mode;
- DeScratchISlider *threshold, *asymmetry;
+ DeScratchISlider *threshold;
+ DeScratchFSlider *asymmetry;
DeScratchISlider *min_width, *max_width;
DeScratchFSlider *min_len, *max_len;
DeScratchISlider *blur_len;
DeScratchFSlider *max_angle;
DeScratchISlider *border;
DeScratchMark *mark;
+ DeScratchEdgeOnly *edge_only;
DeScratchFSlider *ffade;
DeScratchReset *reset;
};
DeScratchWindow *win;
};
+class DeScratchEdgeOnly : public BC_CheckBox
+{
+public:
+ DeScratchEdgeOnly(DeScratchWindow *win, int x, int y);
+ ~DeScratchEdgeOnly();
+ int handle_event();
+
+ DeScratchWindow *win;
+};
+
class DeScratchReset : public BC_GenericButton
{
public:
{
strcpy(font, "fixed");
strcpy(encoding, DEFAULT_ENCODING);
- style = 0;
+ style = FONT_ALIAS;
size = 24;
color = BLACK;
alpha = 0xff;
FT_Done_FreeType(freetype_library);
}
+static inline void to_mono(VFrame *data)
+{
+ if( !data ) return;
+ int w = data->get_w(), h = data->get_h();
+ uint8_t **rows = data->get_rows();
+ for( int y=0; y<h; ++y ) {
+ uint8_t *dp = rows[y];
+ for( int x=0; x<w; ++x,++dp ) *dp = *dp >= 0x80 ? 0xff : 0;
+ }
+}
+
void GlyphUnit::process_package(LoadPackage *package)
{
GlyphPackage *pkg = (GlyphPackage*)package;
//printf("GlyphUnit::process_package 2\n");
}
+
+ if( !(glyph->style & FONT_ALIAS) ) {
+ to_mono(glyph->data);
+ to_mono(glyph->data_stroke);
+ }
}
}
: TitleStack<int>(parser, 0)
{
}
+TitleCurAlias::TitleCurAlias(TitleParser *parser, TitleMain *plugin)
+ : TitleStack<int>(parser, (plugin->config.style & FONT_ALIAS) ? 1 : 0)
+{
+}
TitleCurSuper::TitleCurSuper(TitleParser *parser, TitleMain *plugin)
: TitleStack<int>(parser, 0)
{
cur_under(this, plugin),
cur_blink(this, plugin),
cur_fixed(this, plugin),
+ cur_alias(this, plugin),
cur_super(this, plugin)
{
bfr = out = plugin->config.wtext;
return 0;
}
+int TitleCurAlias::set(const char *txt)
+{
+ int alias = !*txt ? 1 : strtol(txt,(char **)&txt,0);
+ if( *txt ) return 1;
+ push(alias);
+ return 0;
+}
+
int TitleCurSuper::set(const char *txt)
{
int super = !*txt ? 1 : strtol(txt,(char **)&txt,0);
if( !strcmp(id,KW_UL) ) return ret>1 ? cur_under.unset(text) : cur_under.set(text);
if( !strcmp(id,KW_BLINK) ) return ret>1 ? cur_blink.unset(text) : cur_blink.set(text);
if( !strcmp(id,KW_FIXED) ) return ret>1 ? cur_fixed.unset(text) : cur_fixed.set(text);
+ if( !strcmp(id,KW_ALIAS) ) return ret>1 ? cur_alias.unset(text) : cur_alias.set(text);
if( !strcmp(id,KW_SUP) ) return ret>1 ? cur_super.unset(text) : cur_super.set(text);
return 1;
}
if( cur_bold ) cur_style |= BC_FONT_BOLD;
int cur_italic = wchrs.cur_italic;
if( cur_italic ) cur_style |= BC_FONT_ITALIC;
+ int cur_alias = wchrs.cur_alias;
+ if( cur_alias ) cur_style |= FONT_ALIAS;
int cur_super = wchrs.cur_super;
if( cur_super ) cur_size /= 2;
int exists = 0;
int cur_style = 0;
int cur_bold = wchrs.cur_bold;
if( cur_bold ) cur_style |= BC_FONT_BOLD;
+ int cur_alias = wchrs.cur_alias;
+ if( cur_alias ) cur_style |= FONT_ALIAS;
int cur_italic = wchrs.cur_italic;
if( cur_italic ) cur_style |= BC_FONT_ITALIC;
short nx = cur_nudge >> 16, ny = cur_nudge;
#define KW_UL _("ul")
#define KW_BLINK _("blink")
#define KW_FIXED _("fixed")
+#define KW_ALIAS _("alias")
#define KW_SUP _("sup")
#define KW_PNG _("png")
class TitleCurUnder;
class TitleCurBlink;
class TitleCurFixed;
+class TitleCurAlias;
class TitleCurSuper;
class TitleCurNudge;
class TitleParser;
// char types
#define CHAR_GLYPH 0
#define CHAR_IMAGE 1
+
// flags
#define FLAG_UNDER 0x0001
#define FLAG_FIXED 0x0002
#define FLAG_SUBER 0x0008
#define FLAG_BLINK 0x0010
+#define FONT_ALIAS 0x08
+
class TitleConfig
{
public:
int set(const char *txt);
};
+class TitleCurAlias : public TitleStack<int> {
+public:
+ TitleCurAlias(TitleParser *parser, TitleMain *plugin);
+ int set(const char *txt);
+};
+
class TitleCurSuper : public TitleStack<int> {
public:
TitleCurSuper(TitleParser *parser, TitleMain *plugin);
TitleCurUnder cur_under;
TitleCurBlink cur_blink;
TitleCurFixed cur_fixed;
+ TitleCurAlias cur_alias;
TitleCurSuper cur_super;
TitleParser(TitleMain *main);
eprintf("drag enabled, but compositor already grabbed\n");
}
+ add_tool(alias = new TitleAlias(client, this, x, y+110));
+ if( alias->get_w() > w1 ) w1 = drag->get_w();
+
x += w1 + margin;
add_tool(justify_title = new BC_Title(x, y, _("Justify:")));
add_tool(left = new TitleLeft(client, this, x, y + 20));
if( fade_out->get_w() > w1 ) w1 = fade_out->get_w();
x += w1 + margin;
- add_tool(speed_title = new BC_Title(x, y1=y, _("Speed:")));
+ add_tool(speed_title = new BC_Title(x, y, _("Speed:")));
w1 = speed_title->get_w();
- y += speed_title->get_h() + 5;
+ y += speed_title->get_h() + 5; y1 = y;
speed = new TitleSpeed(client, this, x, y);
speed->create_objects();
if( speed->get_w() > w1 ) w1 = speed->get_w();
italic->reposition_window(italic->get_x(), italic->get_y());
bold->reposition_window(bold->get_x(), bold->get_y());
drag->reposition_window(drag->get_x(), drag->get_y());
+ alias->reposition_window(alias->get_x(), alias->get_y());
size_title->reposition_window(size_title->get_x(), size_title->get_y());
size->reposition_window(size->get_x(), size->get_y());
size_tumbler->reposition_window(size_tumbler->get_x(), size_tumbler->get_y());
title_h->update((int64_t)client->config.title_h);
italic->update(client->config.style & BC_FONT_ITALIC);
bold->update(client->config.style & BC_FONT_BOLD);
+ alias->update(client->config.style & FONT_ALIAS);
size->update(client->config.size);
motion->update(TitleMain::motion_to_text(client->config.motion_strategy));
loop->update(client->config.loop);
return 1;
}
+TitleAlias::TitleAlias(TitleMain *client, TitleWindow *window, int x, int y)
+ : BC_CheckBox(x, y, client->config.style & FONT_ALIAS, _("Alias"))
+{
+ this->client = client;
+ this->window = window;
+}
+
+int TitleAlias::handle_event()
+{
+ client->config.style =
+ (client->config.style & ~FONT_ALIAS) |
+ (get_value() ? FONT_ALIAS : 0);
+ window->send_configure_change();
+ return 1;
+}
+
TitleBold::TitleBold(TitleMain *client, TitleWindow *window, int x, int y)
: BC_CheckBox(x, y, client->config.style & BC_FONT_BOLD, _("Bold"))
{
sub_menu->add_subitem("%s 10",item);
sub_menu->add_subitem("%s 0",item);
sub_menu->add_subitem("/%s",item);
+ add_item(cur_item = new TitleCurItem(this, item = KW_ALIAS));
+ cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
+ sub_menu->add_subitem("%s 1",item);
+ sub_menu->add_subitem("%s 0",item);
+ sub_menu->add_subitem("/%s",item);
add_item(cur_item = new TitleCurItem(this, item = KW_SUP));
cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
sub_menu->add_subitem("%s 1",item);
class TitleFontTumble;
class TitleSizeTumble;
class TitleItalic;
+class TitleAlias;
class TitleBold;
class TitleDrag;
class TitleSize;
TitleStroker *stroker;
BC_Title *style_title;
TitleItalic *italic;
+ TitleAlias *alias;
TitleBold *bold;
TitleDrag *drag;
TitleCurPopup *cur_popup;
};
-
+class TitleAlias : public BC_CheckBox
+{
+public:
+ TitleAlias(TitleMain *client, TitleWindow *window, int x, int y);
+ int handle_event();
+ TitleMain *client;
+ TitleWindow *window;
+};
class TitleItalic : public BC_CheckBox
{
public: