1 #include "colormodels.h"
5 #include "quarkwindow.h"
11 #define _(String) gettext(String)
12 #define gettext_noop(String) String
13 #define N_(String) gettext_noop (String)
15 PluginClient* new_plugin(PluginServer *server)
17 return new SharpenMain(server);
20 SharpenMain::SharpenMain(PluginServer *server)
21 : PluginVClient(server)
28 SharpenMain::~SharpenMain()
32 // Set result to 0 to indicate a server side close
33 thread->window->set_done(0);
34 thread->completion.lock();
42 char* SharpenMain::plugin_title() { return _("Quark"); }
43 int SharpenMain::is_realtime() { return 1; }
45 VFrame* SharpenMain::new_picon()
47 return new VFrame(picon_png);
51 int SharpenMain::start_realtime()
54 last_sharpness = sharpness;
56 total_engines = smp > 1 ? 2 : 1;
57 engine = new SharpenEngine*[total_engines];
58 for(int i = 0; i < total_engines; i++)
60 engine[i] = new SharpenEngine(this);
66 int SharpenMain::stop_realtime()
68 for(int i = 0; i < total_engines; i++)
76 int SharpenMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
82 get_luts(pos_lut, neg_lut, input_ptr->get_color_model());
87 row_step = (interlace || horizontal) ? 2 : 1;
89 for(j = 0; j < row_step; j += total_engines)
91 for(k = 0; k < total_engines && k + j < row_step; k++)
93 engine[k]->start_process_frame(input_ptr, input_ptr, k + j);
95 for(k = 0; k < total_engines && k + j < row_step; k++)
97 engine[k]->wait_process_frame();
102 if(input_ptr->get_rows()[0] != output_ptr->get_rows()[0])
104 output_ptr->copy_from(input_ptr);
109 int SharpenMain::show_gui()
111 load_configuration();
112 thread = new SharpenThread(this);
117 int SharpenMain::set_string()
119 if(thread) thread->window->set_title(gui_string);
123 void SharpenMain::raise_window()
127 thread->window->raise_window();
128 thread->window->flush();
132 int SharpenMain::load_defaults()
134 char directory[1024], string[1024];
135 // set the default directory
136 sprintf(directory, "%squark.rc", BCASTDIR);
139 defaults = new Defaults(directory);
142 sharpness = defaults->get("SHARPNESS", 50);
143 interlace = defaults->get("INTERLACE", 0);
144 horizontal = defaults->get("HORIZONTAL", 0);
145 luminance = defaults->get("LUMINANCE", 0);
149 int SharpenMain::save_defaults()
151 defaults->update("SHARPNESS", sharpness);
152 defaults->update("INTERLACE", interlace);
153 defaults->update("HORIZONTAL", horizontal);
154 defaults->update("LUMINANCE", luminance);
159 void SharpenMain::load_configuration()
161 KeyFrame *prev_keyframe, *next_keyframe;
162 //printf("BlurMain::load_configuration 1\n");
164 prev_keyframe = get_prev_keyframe(-1);
165 next_keyframe = get_next_keyframe(-1);
166 // Must also switch between interpolation between keyframes and using first keyframe
167 //printf("BlurMain::load_configuration %s\n", prev_keyframe->data);
168 read_data(prev_keyframe);
172 int SharpenMain::get_luts(int *pos_lut, int *neg_lut, int color_model)
174 int i, inv_sharpness, vmax;
176 vmax = cmodel_calculate_max(color_model);
178 inv_sharpness = (int)(100 - sharpness);
179 if(horizontal) inv_sharpness /= 2;
180 if(inv_sharpness < 1) inv_sharpness = 1;
182 for(i = 0; i < vmax + 1; i++)
184 pos_lut[i] = 800 * i / inv_sharpness;
185 neg_lut[i] = (4 + pos_lut[i] - (i << 3)) >> 3;
191 void SharpenMain::save_data(KeyFrame *keyframe)
195 // cause data to be stored directly in text
196 output.set_shared_string(keyframe->data, MESSAGESIZE);
197 output.tag.set_title("SHARPNESS");
198 output.tag.set_property("VALUE", sharpness);
203 output.tag.set_title("INTERLACE");
209 output.tag.set_title("HORIZONTAL");
215 output.tag.set_title("LUMINANCE");
218 output.terminate_string();
221 void SharpenMain::read_data(KeyFrame *keyframe)
225 input.set_shared_string(keyframe->data, strlen(keyframe->data));
228 int new_interlace = 0;
229 int new_horizontal = 0;
230 int new_luminance = 0;
234 result = input.read_tag();
238 if(input.tag.title_is("SHARPNESS"))
240 sharpness = input.tag.get_property("VALUE", sharpness);
241 last_sharpness = sharpness;
244 if(input.tag.title_is("INTERLACE"))
249 if(input.tag.title_is("HORIZONTAL"))
254 if(input.tag.title_is("LUMINANCE"))
261 interlace = new_interlace;
262 horizontal = new_horizontal;
263 luminance = new_luminance;
265 if(sharpness > MAXSHARPNESS)
266 sharpness = MAXSHARPNESS;
268 if(sharpness < 0) sharpness = 0;
272 thread->window->sharpen_slider->update((int)sharpness);
273 thread->window->sharpen_interlace->update(interlace);
274 thread->window->sharpen_horizontal->update(horizontal);
275 thread->window->sharpen_luminance->update(luminance);
282 SharpenEngine::SharpenEngine(SharpenMain *plugin)
285 this->plugin = plugin;
287 for(int i = 0; i < 4; i++)
289 neg_rows[i] = new int[plugin->project_frame_w * 4];
296 SharpenEngine::~SharpenEngine()
302 for(int i = 0; i < 4; i++)
304 delete [] neg_rows[i];
308 int SharpenEngine::start_process_frame(VFrame *output, VFrame *input, int field)
310 this->output = output;
317 int SharpenEngine::wait_process_frame()
323 #define FILTER(components, vmax, wordsize) \
325 int *pos_lut = plugin->pos_lut; \
327 /* Skip first pixel in row */ \
328 memcpy(dst, src, components * wordsize); \
337 pixel = pos_lut[src[0]] - \
338 neg0[-components] - \
341 neg1[-components] - \
343 neg2[-components] - \
346 pixel = (pixel + 4) >> 3; \
347 if(pixel < 0) dst[0] = 0; \
349 if(pixel > vmax) dst[0] = vmax; \
353 pixel = pos_lut[src[1]] - \
354 neg0[-components + 1] - \
356 neg0[components + 1] - \
357 neg1[-components + 1] - \
358 neg1[components + 1] - \
359 neg2[-components + 1] - \
361 neg2[components + 1]; \
362 pixel = (pixel + 4) >> 3; \
363 if(pixel < 0) dst[1] = 0; \
365 if(pixel > vmax) dst[1] = vmax; \
369 pixel = pos_lut[src[2]] - \
370 neg0[-components + 2] - \
372 neg0[components + 2] - \
373 neg1[-components + 2] - \
374 neg1[components + 2] - \
375 neg2[-components + 2] - \
377 neg2[components + 2]; \
378 pixel = (pixel + 4) >> 3; \
379 if(pixel < 0) dst[2] = 0; \
381 if(pixel > vmax) dst[2] = vmax; \
385 if(components == 4) \
391 neg0 += components; \
392 neg1 += components; \
393 neg2 += components; \
397 /* Skip last pixel in row */ \
398 memcpy(dst, src, components * wordsize); \
401 void SharpenEngine::filter(int components,
411 FILTER(components, vmax, wordsize);
414 void SharpenEngine::filter(int components,
424 FILTER(components, vmax, wordsize);
433 #define SHARPEN(components, wordsize, wordtype, vmax) \
436 unsigned char **input_rows, **output_rows; \
438 input_rows = input->get_rows(); \
439 output_rows = output->get_rows(); \
440 src_rows[0] = input_rows[field]; \
441 src_rows[1] = input_rows[field]; \
442 src_rows[2] = input_rows[field]; \
443 src_rows[3] = input_rows[field]; \
445 for(int j = 0; j < plugin->project_frame_w; j++) \
447 for(int k = 0; k < components; k++) \
448 neg_rows[0][j * components + k] = plugin->neg_lut[((wordtype*)src_rows[0])[j * components + k]]; \
454 for(int i = field; i < plugin->project_frame_h; i += plugin->row_step) \
456 if((i + plugin->row_step) < plugin->project_frame_h) \
458 if(count >= 3) count--; \
460 src_rows[row] = input_rows[i + plugin->row_step]; \
461 for(int k = 0; k < plugin->project_frame_w; k++) \
463 for(int j = 0; j < components; j++) \
464 neg_rows[row][k * components + j] = plugin->neg_lut[((wordtype*)src_rows[row])[k * components + j]]; \
468 row = (row + 1) & 3; \
475 dst_row = output_rows[i]; \
478 /* Do the filter */ \
479 if(plugin->horizontal) \
483 plugin->project_frame_w, \
484 (wordtype*)src_rows[(row + 2) & 3], \
485 (wordtype*)dst_row, \
486 neg_rows[(row + 2) & 3] + components, \
487 neg_rows[(row + 2) & 3] + components, \
488 neg_rows[(row + 2) & 3] + components); \
493 plugin->project_frame_w, \
494 (wordtype*)src_rows[(row + 2) & 3], \
495 (wordtype*)dst_row, \
496 neg_rows[(row + 1) & 3] + components, \
497 neg_rows[(row + 2) & 3] + components, \
498 neg_rows[(row + 3) & 3] + components); \
504 memcpy(dst_row, src_rows[0], plugin->project_frame_w * components * wordsize); \
506 memcpy(dst_row, src_rows[2], plugin->project_frame_w * components * wordsize); \
511 void SharpenEngine::sharpen_888()
513 SHARPEN(3, 1, unsigned char, 0xff);
516 void SharpenEngine::sharpen_8888()
518 SHARPEN(4, 1, unsigned char, 0xff);
521 void SharpenEngine::sharpen_161616()
523 SHARPEN(3, 2, u_int16_t, 0xffff);
526 void SharpenEngine::sharpen_16161616()
528 SHARPEN(4, 2, u_int16_t, 0xffff);
532 void SharpenEngine::run()
539 output_lock.unlock();
544 switch(input->get_color_model())
561 case BC_RGBA16161616:
562 case BC_YUVA16161616:
567 output_lock.unlock();