2 #include "colormodels.h"
19 REGISTER_PLUGIN(DotMain)
27 DotConfig::DotConfig()
37 DotMain::DotMain(PluginServer *server)
38 : PluginVClient(server)
45 PLUGIN_CONSTRUCTOR_MACRO
50 PLUGIN_DESTRUCTOR_MACRO
52 if(pattern) delete [] pattern;
53 if(sampx) delete [] sampx;
54 if(sampy) delete [] sampy;
62 char* DotMain::plugin_title() { return N_("DotTV"); }
63 int DotMain::is_realtime() { return 1; }
65 NEW_PICON_MACRO(DotMain)
67 SHOW_GUI_MACRO(DotMain, DotThread)
69 SET_STRING_MACRO(DotMain)
71 RAISE_WINDOW_MACRO(DotMain)
74 int DotMain::load_defaults()
79 int DotMain::save_defaults()
84 void DotMain::load_configuration()
89 void DotMain::save_data(KeyFrame *keyframe)
93 void DotMain::read_data(KeyFrame *keyframe)
97 void DotMain::make_pattern()
104 for(i = 0; i < config.dot_max(); i++)
106 /* Generated pattern is a quadrant of a disk. */
107 pat = pattern + (i + 1) * dot_hsize * dot_hsize - 1;
109 // r = (0.2 * i / config.dot_max() + 0.8) * dot_hsize;
111 r = ((double)i / config.dot_max()) * dot_hsize;
113 //printf("make_pattern %f\n", r);
115 for(y = 0; y < dot_hsize; y++)
117 for(x = 0; x < dot_hsize; x++)
120 for(u = 0; u < 4; u++)
122 p = (double)u / 4.0 + y;
125 for(v = 0; v < 4; v++)
127 q = (double)v / 4.0 + x;
137 c = (c > 15) ? 15 : c;
138 //printf("DotMain::make_pattern %d\n", c);
139 *pat-- = (c << 20) | (c << 12) | (c << 4);
140 /* The upper left part of a disk is needed, but generated pattern is a bottom
141 * right part. So I spin the pattern. */
147 void DotMain::init_sampxy_table()
153 for(i = 0; i < dots_width; i++)
159 for(i = 0; i < dots_height; i++)
167 void DotMain::reconfigure()
171 effecttv = new EffectTV(input_ptr->get_w(), input_ptr->get_h());
172 dot_server = new DotServer(this, 1, 1);
175 dot_size = config.dot_size;
176 dot_size = dot_size & 0xfe;
177 dot_hsize = dot_size / 2;
178 dots_width = input_ptr->get_w() / dot_size;
179 dots_height = input_ptr->get_h() / dot_size;
180 pattern = new uint32_t[config.dot_max() *
183 sampx = new int[input_ptr->get_w()];
184 sampy = new int[input_ptr->get_h()];
191 need_reconfigure = 0;
196 int DotMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
198 this->input_ptr = input_ptr;
199 this->output_ptr = output_ptr;
200 load_configuration();
201 if(need_reconfigure) reconfigure();
204 dot_server->process_packages();
211 DotServer::DotServer(DotMain *plugin, int total_clients, int total_packages)
212 : LoadServer(total_clients, total_packages)
214 this->plugin = plugin;
218 LoadClient* DotServer::new_client()
220 return new DotClient(this);
226 LoadPackage* DotServer::new_package()
228 return new DotPackage;
233 void DotServer::init_packages()
235 for(int i = 0; i < get_total_packages(); i++)
237 DotPackage *package = (DotPackage*)get_package(i);
238 package->row1 = plugin->input_ptr->get_h() * i / get_total_packages();
239 package->row2 = plugin->input_ptr->get_h() * (i + 1) / get_total_packages();
250 DotClient::DotClient(DotServer *server)
253 this->plugin = server->plugin;
256 #define COPY_PIXEL(type, components, output, pattern, chroma_offset) \
260 if(sizeof(type) == 2) \
262 output[0] = (pattern & 0xff0000) >> 8; \
263 output[1] = chroma_offset; \
264 output[2] = chroma_offset; \
265 if(components > 3) output[3] = 0xffff; \
269 output[0] = (pattern & 0xff0000) >> 16; \
270 output[1] = chroma_offset; \
271 output[2] = chroma_offset; \
272 if(components > 3) output[3] = 0xff; \
277 if(sizeof(type) == 4) \
279 output[0] = (type)(pattern & 0xff0000) / 0xff0000; \
280 output[1] = (type)(pattern & 0xff00) / 0xff00; \
281 output[2] = (type)(pattern & 0xff) / 0xff; \
282 if(components > 3) output[3] = 1; \
285 if(sizeof(type) == 2) \
287 output[0] = (pattern & 0xff0000) >> 8; \
288 output[1] = (pattern & 0xff00); \
289 output[2] = (pattern & 0xff) << 8; \
290 if(components > 3) output[3] = 0xffff; \
294 output[0] = (pattern & 0xff0000) >> 16; \
295 output[1] = (pattern & 0xff00) >> 8; \
296 output[2] = (pattern & 0xff); \
297 if(components > 3) output[3] = 0xff; \
302 #define DRAW_DOT(type, components, chroma_offset) \
309 c = (c >> (8 - plugin->config.dot_depth)); \
310 pat = plugin->pattern + c * plugin->dot_hsize * plugin->dot_hsize; \
311 output = ((type**)output_rows)[0] + \
314 plugin->input_ptr->get_w() * \
320 for(y = 0; y < plugin->dot_hsize && y_total < plugin->input_ptr->get_h(); y++) \
322 for(x = 0; x < plugin->dot_hsize; x++) \
324 COPY_PIXEL(type, components, output, *pat, chroma_offset); \
325 output += components; \
331 for(x = 0; x < plugin->dot_hsize - 1; x++) \
333 COPY_PIXEL(type, components, output, *pat, chroma_offset); \
334 output += components; \
338 COPY_PIXEL(type, components, output, 0x00000000, chroma_offset); \
340 output += components * (plugin->input_ptr->get_w() - plugin->dot_size + 1); \
341 pat += plugin->dot_hsize + 1; \
345 pat -= plugin->dot_hsize * 2; \
347 for(y = 0; y < plugin->dot_hsize && y_total < plugin->input_ptr->get_h(); y++) \
349 if(y < plugin->dot_hsize - 1) \
351 for(x = 0; x < plugin->dot_hsize; x++) \
353 COPY_PIXEL(type, components, output, *pat, chroma_offset); \
354 output += components; \
360 for(x = 0; x < plugin->dot_hsize - 1; x++) \
362 COPY_PIXEL(type, components, output, *pat, chroma_offset); \
363 output += components; \
367 COPY_PIXEL(type, components, output, 0x00000000, chroma_offset); \
369 output += components * (plugin->input_ptr->get_w() - plugin->dot_size + 1); \
370 pat += -plugin->dot_hsize + 1; \
374 for(x = 0; x < plugin->dot_hsize * 2; x++) \
376 COPY_PIXEL(type, components, output, 0x00000000, chroma_offset); \
377 output += components; \
386 void DotClient::draw_dot(int xx,
389 unsigned char **output_rows,
392 switch(plugin->input_ptr->get_color_model())
395 DRAW_DOT(uint8_t, 3, 0x0);
399 DRAW_DOT(float, 3, 0x0);
403 DRAW_DOT(uint8_t, 3, 0x80);
407 DRAW_DOT(float, 4, 0x0);
411 DRAW_DOT(uint8_t, 4, 0x0);
415 DRAW_DOT(uint8_t, 4, 0x80);
419 DRAW_DOT(uint16_t, 3, 0x0);
423 DRAW_DOT(uint16_t, 3, 0x8000);
426 case BC_RGBA16161616:
427 DRAW_DOT(uint16_t, 4, 0x0);
429 case BC_YUVA16161616:
430 DRAW_DOT(uint16_t, 4, 0x8000);
435 #define RGB_TO_Y(type, is_yuv) \
437 type *row_local = (type*)row; \
439 if(sizeof(type) == 4) \
441 int r = (int)(row_local[0] * 0xff); \
442 int g = (int)(row_local[0] * 0xff); \
443 int b = (int)(row_local[0] * 0xff); \
447 i = plugin->effecttv->RtoY[r] + \
448 plugin->effecttv->RtoY[g] + \
449 plugin->effecttv->RtoY[b]; \
452 if(sizeof(type) == 2) \
455 i = (int)row_local[0] >> 8; \
458 i = plugin->effecttv->RtoY[(int)row_local[0] >> 8]; \
459 i += plugin->effecttv->GtoY[(int)row_local[1] >> 8]; \
460 i += plugin->effecttv->BtoY[(int)row_local[2] >> 8]; \
466 i = (int)row_local[0]; \
469 i = plugin->effecttv->RtoY[(int)row_local[0]]; \
470 i += plugin->effecttv->GtoY[(int)row_local[1]]; \
471 i += plugin->effecttv->BtoY[(int)row_local[2]]; \
476 unsigned char DotClient::RGBtoY(unsigned char *row, int color_model)
484 RGB_TO_Y(uint8_t, 0);
492 RGB_TO_Y(uint8_t, 1);
495 case BC_RGBA16161616:
496 RGB_TO_Y(uint16_t, 0);
499 case BC_YUVA16161616:
500 RGB_TO_Y(uint16_t, 1);
508 void DotClient::process_package(LoadPackage *package)
512 DotPackage *local_package = (DotPackage*)package;
513 unsigned char **input_rows = plugin->input_ptr->get_rows() + local_package->row1;
514 unsigned char **output_rows = plugin->output_ptr->get_rows() + local_package->row1;
515 int width = plugin->input_ptr->get_w();
516 int height = local_package->row2 - local_package->row1;
519 for(y = 0; y < plugin->dots_height; y++)
521 sy = plugin->sampy[y];
522 for(x = 0; x < plugin->dots_width; x++)
524 sx = plugin->sampx[x];
526 //printf("DotClient::process_package %d\n",
527 // RGBtoY(&input_rows[sy][sx * plugin->input_ptr->get_bytes_per_pixel()],
528 // plugin->input_ptr->get_color_model()));
531 RGBtoY(&input_rows[sy][sx * plugin->input_ptr->get_bytes_per_pixel()],
532 plugin->input_ptr->get_color_model()),
534 plugin->input_ptr->get_color_model());
541 DotPackage::DotPackage()