2 #include "colormodels.h"
14 #define _(String) gettext(String)
15 #define gettext_noop(String) String
16 #define N_(String) gettext_noop (String)
18 PluginClient* new_plugin(PluginServer *server)
20 return new DotMain(server);
33 DotConfig::DotConfig()
43 DotMain::DotMain(PluginServer *server)
44 : PluginVClient(server)
60 // Set result to 0 to indicate a server side close
61 thread->window->set_done(0);
62 thread->completion.lock();
66 if(pattern) delete [] pattern;
67 if(sampx) delete [] sampx;
68 if(sampy) delete [] sampy;
75 if(defaults) delete defaults;
78 char* DotMain::plugin_title() { return _("DotTV"); }
79 int DotMain::is_realtime() { return 1; }
81 NEW_PICON_MACRO(DotMain)
83 SHOW_GUI_MACRO(DotMain, DotThread)
85 SET_STRING_MACRO(DotMain)
87 RAISE_WINDOW_MACRO(DotMain)
90 int DotMain::load_defaults()
95 int DotMain::save_defaults()
100 void DotMain::load_configuration()
105 void DotMain::save_data(KeyFrame *keyframe)
109 void DotMain::read_data(KeyFrame *keyframe)
113 void DotMain::make_pattern()
120 for(i = 0; i < config.dot_max(); i++)
122 /* Generated pattern is a quadrant of a disk. */
123 pat = pattern + (i + 1) * dot_hsize * dot_hsize - 1;
125 // r = (0.2 * i / config.dot_max() + 0.8) * dot_hsize;
127 r = ((double)i / config.dot_max()) * dot_hsize;
129 //printf("make_pattern %f\n", r);
131 for(y = 0; y < dot_hsize; y++)
133 for(x = 0; x < dot_hsize; x++)
136 for(u = 0; u < 4; u++)
138 p = (double)u / 4.0 + y;
141 for(v = 0; v < 4; v++)
143 q = (double)v / 4.0 + x;
153 c = (c > 15) ? 15 : c;
154 //printf("DotMain::make_pattern %d\n", c);
155 *pat-- = (c << 20) | (c << 12) | (c << 4);
156 /* The upper left part of a disk is needed, but generated pattern is a bottom
157 * right part. So I spin the pattern. */
163 void DotMain::init_sampxy_table()
169 for(i = 0; i < dots_width; i++)
175 for(i = 0; i < dots_height; i++)
183 void DotMain::reconfigure()
187 effecttv = new EffectTV(input_ptr->get_w(), input_ptr->get_h());
188 dot_server = new DotServer(this, 1, 1);
191 dot_size = config.dot_size;
192 dot_size = dot_size & 0xfe;
193 dot_hsize = dot_size / 2;
194 dots_width = input_ptr->get_w() / dot_size;
195 dots_height = input_ptr->get_h() / dot_size;
196 pattern = new uint32_t[config.dot_max() *
199 sampx = new int[input_ptr->get_w()];
200 sampy = new int[input_ptr->get_h()];
207 need_reconfigure = 0;
212 int DotMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
214 this->input_ptr = input_ptr;
215 this->output_ptr = output_ptr;
216 load_configuration();
217 if(need_reconfigure) reconfigure();
220 dot_server->process_packages();
227 DotServer::DotServer(DotMain *plugin, int total_clients, int total_packages)
228 : LoadServer(total_clients, total_packages)
230 this->plugin = plugin;
234 LoadClient* DotServer::new_client()
236 return new DotClient(this);
242 LoadPackage* DotServer::new_package()
244 return new DotPackage;
249 void DotServer::init_packages()
251 for(int i = 0; i < total_packages; i++)
253 DotPackage *package = (DotPackage*)packages[i];
254 package->row1 = plugin->input_ptr->get_h() / total_packages * i;
255 package->row2 = package->row1 + plugin->input_ptr->get_h() / total_packages;
256 if(i >= total_packages - 1)
257 package->row2 = plugin->input_ptr->get_h();
268 DotClient::DotClient(DotServer *server)
271 this->plugin = server->plugin;
274 #define COPY_PIXEL(type, components, output, pattern, chroma_offset) \
278 if(sizeof(type) == 2) \
280 output[0] = (pattern & 0xff0000) >> 8; \
281 output[1] = chroma_offset; \
282 output[2] = chroma_offset; \
283 if(components > 3) output[3] = 0xffff; \
287 output[0] = (pattern & 0xff0000) >> 16; \
288 output[1] = chroma_offset; \
289 output[2] = chroma_offset; \
290 if(components > 3) output[3] = 0xff; \
295 if(sizeof(type) == 2) \
297 output[0] = (pattern & 0xff0000) >> 8; \
298 output[1] = (pattern & 0xff00); \
299 output[2] = (pattern & 0xff) << 8; \
300 if(components > 3) output[3] = 0xffff; \
304 output[0] = (pattern & 0xff0000) >> 16; \
305 output[1] = (pattern & 0xff00) >> 8; \
306 output[2] = (pattern & 0xff); \
307 if(components > 3) output[3] = 0xff; \
312 #define DRAW_DOT(type, components, chroma_offset) \
319 c = (c >> (8 - plugin->config.dot_depth)); \
320 pat = plugin->pattern + c * plugin->dot_hsize * plugin->dot_hsize; \
321 output = ((type**)output_rows)[0] + \
324 plugin->input_ptr->get_w() * \
330 for(y = 0; y < plugin->dot_hsize && y_total < plugin->input_ptr->get_h(); y++) \
332 for(x = 0; x < plugin->dot_hsize; x++) \
334 COPY_PIXEL(type, components, output, *pat, chroma_offset); \
335 output += components; \
341 for(x = 0; x < plugin->dot_hsize - 1; x++) \
343 COPY_PIXEL(type, components, output, *pat, chroma_offset); \
344 output += components; \
348 COPY_PIXEL(type, components, output, 0x00000000, chroma_offset); \
350 output += components * (plugin->input_ptr->get_w() - plugin->dot_size + 1); \
351 pat += plugin->dot_hsize + 1; \
355 pat -= plugin->dot_hsize * 2; \
357 for(y = 0; y < plugin->dot_hsize && y_total < plugin->input_ptr->get_h(); y++) \
359 if(y < plugin->dot_hsize - 1) \
361 for(x = 0; x < plugin->dot_hsize; x++) \
363 COPY_PIXEL(type, components, output, *pat, chroma_offset); \
364 output += components; \
370 for(x = 0; x < plugin->dot_hsize - 1; x++) \
372 COPY_PIXEL(type, components, output, *pat, chroma_offset); \
373 output += components; \
377 COPY_PIXEL(type, components, output, 0x00000000, chroma_offset); \
379 output += components * (plugin->input_ptr->get_w() - plugin->dot_size + 1); \
380 pat += -plugin->dot_hsize + 1; \
384 for(x = 0; x < plugin->dot_hsize * 2; x++) \
386 COPY_PIXEL(type, components, output, 0x00000000, chroma_offset); \
387 output += components; \
396 void DotClient::draw_dot(int xx,
399 unsigned char **output_rows,
402 switch(plugin->input_ptr->get_color_model())
405 DRAW_DOT(uint8_t, 3, 0x0);
409 DRAW_DOT(uint8_t, 3, 0x80);
413 DRAW_DOT(uint8_t, 4, 0x0);
417 DRAW_DOT(uint8_t, 4, 0x80);
421 DRAW_DOT(uint16_t, 3, 0x0);
425 DRAW_DOT(uint16_t, 3, 0x8000);
428 case BC_RGBA16161616:
429 DRAW_DOT(uint16_t, 4, 0x0);
431 case BC_YUVA16161616:
432 DRAW_DOT(uint16_t, 4, 0x8000);
437 #define RGB_TO_Y(type) \
439 type *row_local = (type*)row; \
441 if(sizeof(type) == 2) \
443 i = plugin->effecttv->RtoY[row_local[0] >> 8]; \
444 i += plugin->effecttv->GtoY[row_local[1] >> 8]; \
445 i += plugin->effecttv->BtoY[row_local[2] >> 8]; \
449 i = plugin->effecttv->RtoY[row_local[0]]; \
450 i += plugin->effecttv->GtoY[row_local[1]]; \
451 i += plugin->effecttv->BtoY[row_local[2]]; \
453 /*printf("RGB_TO_Y %d %d %d %d\n", plugin->effecttv->RtoY[row_local[0]], plugin->effecttv->GtoY[row_local[1]], plugin->effecttv->BtoY[row_local[2]], i);*/ \
456 unsigned char DotClient::RGBtoY(unsigned char *row, int color_model)
474 case BC_RGBA16161616:
475 case BC_YUVA16161616:
484 void DotClient::process_package(LoadPackage *package)
488 DotPackage *local_package = (DotPackage*)package;
489 unsigned char **input_rows = plugin->input_ptr->get_rows() + local_package->row1;
490 unsigned char **output_rows = plugin->output_ptr->get_rows() + local_package->row1;
491 int width = plugin->input_ptr->get_w();
492 int height = local_package->row2 - local_package->row1;
495 for(y = 0; y < plugin->dots_height; y++)
497 sy = plugin->sampy[y];
498 for(x = 0; x < plugin->dots_width; x++)
500 sx = plugin->sampx[x];
502 //printf("DotClient::process_package %d\n",
503 // RGBtoY(&input_rows[sy][sx * plugin->input_ptr->get_bytes_per_pixel()],
504 // plugin->input_ptr->get_color_model()));
507 RGBtoY(&input_rows[sy][sx * plugin->input_ptr->get_bytes_per_pixel()],
508 plugin->input_ptr->get_color_model()),
510 plugin->input_ptr->get_color_model());
517 DotPackage::DotPackage()