ffdc0ae565541e2236ec0b7b7154104487c5b5eb
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / polar / polar.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "bcdisplayinfo.h"
23 #include "clip.h"
24 #include "bchash.h"
25 #include "filexml.h"
26 #include "guicast.h"
27 #include "keyframe.h"
28 #include "language.h"
29 #include "loadbalance.h"
30 #include "pluginvclient.h"
31 #include "theme.h"
32 #include "vframe.h"
33
34
35
36 #include <string.h>
37 #include <stdint.h>
38
39
40 #define WITHIN(a, b, c) ((((a) <= (b)) && ((b) <= (c))) ? 1 : 0)
41
42 #define RESET_ALL   0
43 #define RESET_DEPTH 1
44 #define RESET_ANGLE 2
45
46 class PolarEffect;
47 class PolarEngine;
48 class PolarWindow;
49 class PolarReset;
50 class PolarSliderClr;
51
52
53 class PolarConfig
54 {
55 public:
56         PolarConfig();
57
58         void reset(int clear);
59         void copy_from(PolarConfig &src);
60         int equivalent(PolarConfig &src);
61         void interpolate(PolarConfig &prev,
62                 PolarConfig &next,
63                 long prev_frame,
64                 long next_frame,
65                 long current_frame);
66
67         int polar_to_rectangular;
68         float depth;
69         float angle;
70         int backwards;
71         int invert;
72 };
73
74
75
76 class PolarDepth : public BC_FSlider
77 {
78 public:
79         PolarDepth(PolarEffect *plugin, int x, int y);
80         int handle_event();
81         PolarEffect *plugin;
82 };
83
84 class PolarAngle : public BC_FSlider
85 {
86 public:
87         PolarAngle(PolarEffect *plugin, int x, int y);
88         int handle_event();
89         PolarEffect *plugin;
90 };
91
92 class PolarReset : public BC_GenericButton
93 {
94 public:
95         PolarReset(PolarEffect *plugin, PolarWindow *window, int x, int y);
96         ~PolarReset();
97         int handle_event();
98         PolarEffect *plugin;
99         PolarWindow *window;
100 };
101
102 class PolarSliderClr : public BC_Button
103 {
104 public:
105         PolarSliderClr(PolarEffect *plugin, PolarWindow *window, int x, int y, int w, int clear);
106         ~PolarSliderClr();
107         int handle_event();
108         PolarEffect *plugin;
109         PolarWindow *window;
110         int clear;
111 };
112
113 class PolarWindow : public PluginClientWindow
114 {
115 public:
116         PolarWindow(PolarEffect *plugin);
117         void create_objects();
118         void update_gui(int clear);
119         PolarEffect *plugin;
120         PolarDepth *depth;
121         PolarAngle *angle;
122         PolarReset *reset;
123         PolarSliderClr *depthClr;
124         PolarSliderClr *angleClr;
125 };
126
127
128
129
130
131 class PolarPackage : public LoadPackage
132 {
133 public:
134         PolarPackage();
135         int row1, row2;
136 };
137
138 class PolarUnit : public LoadClient
139 {
140 public:
141         PolarUnit(PolarEffect *plugin, PolarEngine *server);
142         void process_package(LoadPackage *package);
143         PolarEffect *plugin;
144 };
145
146 class PolarEngine : public LoadServer
147 {
148 public:
149         PolarEngine(PolarEffect *plugin, int cpus);
150         void init_packages();
151         LoadClient* new_client();
152         LoadPackage* new_package();
153         PolarEffect *plugin;
154 };
155
156 class PolarEffect : public PluginVClient
157 {
158 public:
159         PolarEffect(PluginServer *server);
160         ~PolarEffect();
161
162         PLUGIN_CLASS_MEMBERS(PolarConfig)
163         int process_realtime(VFrame *input, VFrame *output);
164         int is_realtime();
165         void save_data(KeyFrame *keyframe);
166         void read_data(KeyFrame *keyframe);
167         void update_gui();
168
169         PolarEngine *engine;
170         VFrame *temp_frame;
171         VFrame *input, *output;
172         int need_reconfigure;
173 };
174
175
176
177 REGISTER_PLUGIN(PolarEffect)
178
179
180
181 PolarConfig::PolarConfig()
182 {
183         reset(RESET_ALL);
184 }
185
186 void PolarConfig::reset(int clear)
187 {
188         switch(clear) {
189                 case RESET_DEPTH : depth = 1.0;
190                         break;
191                 case RESET_ANGLE : angle = 1.0;
192                         break;
193                 case RESET_ALL :
194                 default:
195                         angle = 1.0;
196                         depth = 1.0;
197                         backwards = 0;
198                         invert = 0;
199                         polar_to_rectangular = 1;
200                         break;
201         }
202 }
203
204 void PolarConfig::copy_from(PolarConfig &src)
205 {
206         this->angle = src.angle;
207         this->depth = src.depth;
208         this->backwards = src.backwards;
209         this->invert = src.invert;
210         this->polar_to_rectangular = src.polar_to_rectangular;
211 }
212
213 int PolarConfig::equivalent(PolarConfig &src)
214 {
215         return EQUIV(this->angle, src.angle) && EQUIV(this->depth, src.depth);
216 }
217
218 void PolarConfig::interpolate(PolarConfig &prev,
219                 PolarConfig &next,
220                 long prev_frame,
221                 long next_frame,
222                 long current_frame)
223 {
224         double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
225         double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
226
227         this->depth = prev.depth * prev_scale + next.depth * next_scale;
228         this->angle = prev.angle * prev_scale + next.angle * next_scale;
229 }
230
231
232
233
234
235
236 PolarWindow::PolarWindow(PolarEffect *plugin)
237  : PluginClientWindow(plugin,
238         330,
239         122,
240         330,
241         122,
242         0)
243 {
244         this->plugin = plugin;
245 }
246
247 void PolarWindow::create_objects()
248 {
249         int x = 10, y = 10, x1 = x + 50;
250         int x2 = 0; int clrBtn_w = 50;
251
252         add_subwindow(new BC_Title(x, y, _("Depth:")));
253         add_subwindow(depth = new PolarDepth(plugin, x1, y));
254         x2 = x1 + depth->get_w() + 10;
255         add_subwindow(depthClr = new PolarSliderClr(plugin, this, x2, y, clrBtn_w, RESET_DEPTH));
256
257         y += 40;
258         add_subwindow(new BC_Title(x, y, _("Angle:")));
259         add_subwindow(angle = new PolarAngle(plugin, x1, y));
260         add_subwindow(angleClr = new PolarSliderClr(plugin, this, x2, y, clrBtn_w, RESET_ANGLE));
261         y += 40;
262         add_subwindow(reset = new PolarReset(plugin, this, x, y));
263
264         show_window();
265         flush();
266 }
267
268 // for Reset button
269 void PolarWindow::update_gui(int clear)
270 {
271         switch(clear) {
272                 case RESET_DEPTH : depth->update(plugin->config.depth);
273                         break;
274                 case RESET_ANGLE : angle->update(plugin->config.angle);
275                         break;
276                 case RESET_ALL :
277                 default:
278                         depth->update(plugin->config.depth);
279                         angle->update(plugin->config.angle);
280                         break;
281         }
282 }
283
284
285
286
287
288 PolarDepth::PolarDepth(PolarEffect *plugin, int x, int y)
289  : BC_FSlider(x,
290                 y,
291                 0,
292                 200,
293                 200,
294                 (float)1,
295                 (float)100,
296                 plugin->config.depth)
297 {
298         this->plugin = plugin;
299 }
300 int PolarDepth::handle_event()
301 {
302         plugin->config.depth = get_value();
303         plugin->send_configure_change();
304         return 1;
305 }
306
307
308
309
310
311 PolarAngle::PolarAngle(PolarEffect *plugin, int x, int y)
312  : BC_FSlider(x,
313                 y,
314                 0,
315                 200,
316                 200,
317                 (float)1,
318                 (float)360,
319                 plugin->config.angle)
320 {
321         this->plugin = plugin;
322 }
323 int PolarAngle::handle_event()
324 {
325         plugin->config.angle = get_value();
326         plugin->send_configure_change();
327         return 1;
328 }
329
330
331
332 PolarReset::PolarReset(PolarEffect *plugin, PolarWindow *window, int x, int y)
333  : BC_GenericButton(x, y, _("Reset"))
334 {
335         this->plugin = plugin;
336         this->window = window;
337 }
338 PolarReset::~PolarReset()
339 {
340 }
341 int PolarReset::handle_event()
342 {
343         plugin->config.reset(RESET_ALL);
344         window->update_gui(RESET_ALL);
345         plugin->send_configure_change();
346         return 1;
347 }
348
349
350 PolarSliderClr::PolarSliderClr(PolarEffect *plugin, PolarWindow *window, int x, int y, int w, int clear)
351  : BC_Button(x, y, w, plugin->get_theme()->get_image_set("reset_button"))
352 {
353         this->plugin = plugin;
354         this->window = window;
355         this->clear = clear;
356 }
357 PolarSliderClr::~PolarSliderClr()
358 {
359 }
360 int PolarSliderClr::handle_event()
361 {
362         // clear==1 ==> Depth slider
363         // clear==2 ==> Angle slider
364         plugin->config.reset(clear);
365         window->update_gui(clear);
366         plugin->send_configure_change();
367         return 1;
368 }
369
370
371
372
373 PolarEffect::PolarEffect(PluginServer *server)
374  : PluginVClient(server)
375 {
376         need_reconfigure = 1;
377         temp_frame = 0;
378         engine = 0;
379
380 }
381
382 PolarEffect::~PolarEffect()
383 {
384
385         if(temp_frame) delete temp_frame;
386         if(engine) delete engine;
387 }
388
389
390
391 const char* PolarEffect::plugin_title() { return N_("Polar"); }
392 int PolarEffect::is_realtime() { return 1; }
393
394
395
396
397 NEW_WINDOW_MACRO(PolarEffect, PolarWindow)
398
399 void PolarEffect::update_gui()
400 {
401         if(thread)
402         {
403                 load_configuration();
404                 thread->window->lock_window();
405                 ((PolarWindow*)thread->window)->angle->update(config.angle);
406                 ((PolarWindow*)thread->window)->depth->update(config.depth);
407                 thread->window->unlock_window();
408         }
409 }
410
411 LOAD_CONFIGURATION_MACRO(PolarEffect, PolarConfig)
412
413
414
415 void PolarEffect::save_data(KeyFrame *keyframe)
416 {
417         FileXML output;
418
419 // cause data to be stored directly in text
420         output.set_shared_output(keyframe->xbuf);
421         output.tag.set_title("POLAR");
422         output.tag.set_property("DEPTH", config.depth);
423         output.tag.set_property("ANGLE", config.angle);
424         output.append_tag();
425         output.tag.set_title("/POLAR");
426         output.append_tag();
427         output.append_newline();
428         output.terminate_string();
429 }
430
431 void PolarEffect::read_data(KeyFrame *keyframe)
432 {
433         FileXML input;
434
435         input.set_shared_input(keyframe->xbuf);
436
437         while(!input.read_tag())
438         {
439                 if(input.tag.title_is("POLAR"))
440                 {
441                         config.depth = input.tag.get_property("DEPTH", config.depth);
442                         config.angle = input.tag.get_property("ANGLE", config.angle);
443                 }
444         }
445 }
446
447 int PolarEffect::process_realtime(VFrame *input, VFrame *output)
448 {
449         need_reconfigure |= load_configuration();
450
451         this->input = input;
452         this->output = output;
453
454         if(EQUIV(config.depth, 0) || EQUIV(config.angle, 0))
455         {
456                 if(input->get_rows()[0] != output->get_rows()[0])
457                         output->copy_from(input);
458         }
459         else
460         {
461                 if(input->get_rows()[0] == output->get_rows()[0])
462                 {
463                         if(!temp_frame)
464                                 temp_frame = new VFrame(input->get_w(), input->get_h(),
465                                         input->get_color_model(), 0);
466                         temp_frame->copy_from(input);
467                         this->input = temp_frame;
468                 }
469
470
471                 if(!engine) engine = new PolarEngine(this, PluginClient::smp + 1);
472
473                 engine->process_packages();
474         }
475         return 0;
476 }
477
478
479
480
481
482 PolarPackage::PolarPackage()
483  : LoadPackage()
484 {
485 }
486
487
488
489
490 PolarUnit::PolarUnit(PolarEffect *plugin, PolarEngine *server)
491  : LoadClient(server)
492 {
493         this->plugin = plugin;
494 }
495
496
497 static int calc_undistorted_coords(int wx,
498                          int wy,
499                          int w,
500                          int h,
501                          float depth,
502                          double angle,
503                          int polar_to_rectangular,
504                          int backwards,
505                          int inverse,
506                          double cen_x,
507                          double cen_y,
508                          double &x,
509                          double &y)
510 {
511         int inside;
512         double phi, phi2;
513         double xx, xm, ym, yy;
514         int xdiff, ydiff;
515         double r;
516         double m;
517         double xmax, ymax, rmax;
518         double x_calc, y_calc;
519         double xi, yi;
520         double circle, angl, t;
521         int x1, x2, y1, y2;
522
523 /* initialize */
524
525         phi = 0.0;
526         r = 0.0;
527
528         x1 = 0;
529         y1 = 0;
530         x2 = w;
531         y2 = h;
532         xdiff = x2 - x1;
533         ydiff = y2 - y1;
534         xm = xdiff / 2.0;
535         ym = ydiff / 2.0;
536         circle = depth;
537         angle = angle;
538         angl = (double)angle / 180.0 * M_PI;
539
540     if(polar_to_rectangular)
541     {
542         if(wx >= cen_x)
543                 {
544                         if(wy > cen_y)
545                 {
546                         phi = M_PI -
547                                         atan(((double)(wx - cen_x)) /
548                                         ((double)(wy - cen_y)));
549                         r   = sqrt(SQR(wx - cen_x) +
550                                         SQR(wy - cen_y));
551                 }
552                         else
553                         if(wy < cen_y)
554                 {
555                         phi = atan(((double)(wx - cen_x)) /
556                                         ((double)(cen_y - wy)));
557                         r   = sqrt(SQR(wx - cen_x) +
558                                         SQR(cen_y - wy));
559                 }
560                         else
561                 {
562                         phi = M_PI / 2;
563                         r   = wx - cen_x;
564                 }
565                 }
566         else
567                 if(wx < cen_x)
568                 {
569                         if(wy < cen_y)
570                 {
571                         phi = 2 * M_PI -
572                                         atan(((double)(cen_x -wx)) /
573                                     ((double)(cen_y - wy)));
574                         r   = sqrt(SQR(cen_x - wx) +
575                                         SQR(cen_y - wy));
576                 }
577                         else
578                         if(wy > cen_y)
579                 {
580                         phi = M_PI +
581                                         atan(((double)(cen_x - wx)) /
582                                         ((double)(wy - cen_y)));
583                         r   = sqrt(SQR(cen_x - wx) +
584                                         SQR(wy - cen_y));
585                 }
586                         else
587                 {
588                         phi = 1.5 * M_PI;
589                         r   = cen_x - wx;
590                 }
591                 }
592         if (wx != cen_x)
593                 {
594                         m = fabs(((double)(wy - cen_y)) /
595                                 ((double)(wx - cen_x)));
596                 }
597         else
598                 {
599                     m = 0;
600                 }
601
602         if(m <= ((double)(y2 - y1) /
603                         (double)(x2 - x1)))
604                 {
605                         if(wx == cen_x)
606                 {
607                         xmax = 0;
608                         ymax = cen_y - y1;
609                 }
610                         else
611                 {
612                         xmax = cen_x - x1;
613                         ymax = m * xmax;
614                 }
615                 }
616         else
617                 {
618                         ymax = cen_y - y1;
619                         xmax = ymax / m;
620                 }
621
622         rmax = sqrt((double)(SQR(xmax) + SQR(ymax)));
623
624         t = ((cen_y - y1) < (cen_x - x1)) ? (cen_y - y1) : (cen_x - x1);
625         rmax = (rmax - t) / 100 * (100 - circle) + t;
626
627         phi = fmod(phi + angl, 2 * M_PI);
628
629         if(backwards)
630                         x_calc = x2 - 1 - (x2 - x1 - 1) / (2 * M_PI) * phi;
631         else
632                         x_calc = (x2 - x1 - 1) / (2 * M_PI) * phi + x1;
633
634         if(inverse)
635                         y_calc = (y2 - y1) / rmax * r + y1;
636         else
637                         y_calc = y2 - (y2 - y1) / rmax * r;
638
639         xi = (int)(x_calc + 0.5);
640         yi = (int)(y_calc + 0.5);
641
642         if(WITHIN(0, xi, w - 1) && WITHIN(0, yi, h - 1))
643                 {
644                         x = x_calc;
645                         y = y_calc;
646
647                         inside = 1;
648                 }
649         else
650                 {
651                         inside = 0;
652                 }
653     }
654         else
655     {
656         if(backwards)
657                         phi = (2 * M_PI) * (x2 - wx) / xdiff;
658         else
659                         phi = (2 * M_PI) * (wx - x1) / xdiff;
660
661         phi = fmod (phi + angl, 2 * M_PI);
662
663         if(phi >= 1.5 * M_PI)
664                         phi2 = 2 * M_PI - phi;
665         else
666                 if (phi >= M_PI)
667                         phi2 = phi - M_PI;
668                 else
669                 if(phi >= 0.5 * M_PI)
670                 phi2 = M_PI - phi;
671                 else
672                 phi2 = phi;
673
674         xx = tan (phi2);
675         if(xx != 0)
676                         m = (double)1.0 / xx;
677         else
678                         m = 0;
679
680         if(m <= ((double)(ydiff) / (double)(xdiff)))
681                 {
682                         if(phi2 == 0)
683                 {
684                         xmax = 0;
685                         ymax = ym - y1;
686                 }
687                         else
688                 {
689                         xmax = xm - x1;
690                         ymax = m * xmax;
691                 }
692                 }
693         else
694                 {
695                         ymax = ym - y1;
696                         xmax = ymax / m;
697                 }
698
699         rmax = sqrt((double)(SQR(xmax) + SQR(ymax)));
700
701         t = ((ym - y1) < (xm - x1)) ? (ym - y1) : (xm - x1);
702
703         rmax = (rmax - t) / 100.0 * (100 - circle) + t;
704
705         if(inverse)
706                         r = rmax * (double)((wy - y1) / (double)(ydiff));
707         else
708                         r = rmax * (double)((y2 - wy) / (double)(ydiff));
709
710         xx = r * sin (phi2);
711         yy = r * cos (phi2);
712
713         if(phi >= 1.5 * M_PI)
714                 {
715                         x_calc = (double)xm - xx;
716                         y_calc = (double)ym - yy;
717                 }
718         else
719                 if(phi >= M_PI)
720                 {
721                 x_calc = (double)xm - xx;
722                 y_calc = (double)ym + yy;
723                 }
724                 else
725                 if(phi >= 0.5 * M_PI)
726             {
727                 x_calc = (double)xm + xx;
728                 y_calc = (double)ym + yy;
729             }
730                 else
731             {
732                 x_calc = (double)xm + xx;
733                 y_calc = (double)ym - yy;
734             }
735
736         xi = (int)(x_calc + 0.5);
737         yi = (int)(y_calc + 0.5);
738
739         if(WITHIN(0, xi, w - 1) &&
740                         WITHIN(0, yi, h - 1))
741                 {
742                         x = x_calc;
743                         y = y_calc;
744
745                         inside = 1;
746         }
747         else
748                 {
749                         inside = 0;
750                 }
751     }
752
753         return inside;
754 }
755
756 static double bilinear(double x, double y, double *values)
757 {
758         double m0, m1;
759         x = fmod(x, 1.0);
760         y = fmod(y, 1.0);
761
762         if(x < 0.0) x += 1.0;
763         if(y < 0.0) y += 1.0;
764
765         m0 = values[0] + x * (values[1] - values[0]);
766         m1 = values[2] + x * (values[3] - values[2]);
767         return m0 + y * (m1 - m0);
768 }
769
770 #define GET_PIXEL(x, y, components, input_rows) \
771         input_rows[CLIP((y), 0, ((h) - 1))] + components * CLIP((x), 0, ((w) - 1))
772
773 #define POLAR_MACRO(type, max, components, chroma_offset) \
774 { \
775         type **in_rows = (type**)plugin->input->get_rows(); \
776         type **out_rows = (type**)plugin->output->get_rows(); \
777         double values[4]; \
778  \
779         for(int y = pkg->row1; y < pkg->row2; y++) \
780         { \
781                 type *output_row = out_rows[y]; \
782  \
783                 for(int x = 0; x < w; x++) \
784                 { \
785                         type *output_pixel = output_row + x * components; \
786                         if(calc_undistorted_coords(x, \
787                                 y, \
788                                 w, \
789                                 h, \
790                                 plugin->config.depth, \
791                                 plugin->config.angle, \
792                                 plugin->config.polar_to_rectangular, \
793                                 plugin->config.backwards, \
794                                 plugin->config.invert, \
795                                 cen_x, \
796                                 cen_y, \
797                                 cx, \
798                                 cy)) \
799                         { \
800                                 type *pixel1 = GET_PIXEL((int)cx,     (int)cy,   components, in_rows); \
801                                 type *pixel2 = GET_PIXEL((int)cx + 1, (int)cy,   components, in_rows); \
802                                 type *pixel3 = GET_PIXEL((int)cx,     (int)cy + 1, components, in_rows); \
803                                 type *pixel4 = GET_PIXEL((int)cx + 1, (int)cy + 1, components, in_rows); \
804  \
805                                 values[0] = pixel1[0]; \
806                                 values[1] = pixel2[0]; \
807                                 values[2] = pixel3[0]; \
808                                 values[3] = pixel4[0]; \
809                                 output_pixel[0] = (type)bilinear(cx, cy, values); \
810  \
811                                 values[0] = pixel1[1]; \
812                                 values[1] = pixel2[1]; \
813                                 values[2] = pixel3[1]; \
814                                 values[3] = pixel4[1]; \
815                                 output_pixel[1] = (type)bilinear(cx, cy, values); \
816  \
817                                 values[0] = pixel1[2]; \
818                                 values[1] = pixel2[2]; \
819                                 values[2] = pixel3[2]; \
820                                 values[3] = pixel4[2]; \
821                                 output_pixel[2] = (type)bilinear(cx, cy, values); \
822  \
823                                 if(components == 4) \
824                                 { \
825                                         values[0] = pixel1[3]; \
826                                         values[1] = pixel2[3]; \
827                                         values[2] = pixel3[3]; \
828                                         values[3] = pixel4[3]; \
829                                         output_pixel[3] = (type)bilinear(cx, cy, values); \
830                                 } \
831                         } \
832                         else \
833                         { \
834                                 output_pixel[0] = 0; \
835                                 output_pixel[1] = chroma_offset; \
836                                 output_pixel[2] = chroma_offset; \
837                                 if(components == 4) output_pixel[3] = max; \
838                         } \
839                 } \
840         } \
841 }
842
843
844 void PolarUnit::process_package(LoadPackage *package)
845 {
846         PolarPackage *pkg = (PolarPackage*)package;
847         int w = plugin->input->get_w();
848         int h = plugin->input->get_h();
849         double cx;
850         double cy;
851         double cen_x = (double)(w - 1) / 2.0;
852         double cen_y = (double)(h - 1) / 2.0;
853
854         switch(plugin->input->get_color_model())
855         {
856                 case BC_RGB_FLOAT:
857                         POLAR_MACRO(float, 1, 3, 0x0)
858                         break;
859                 case BC_RGBA_FLOAT:
860                         POLAR_MACRO(float, 1, 4, 0x0)
861                         break;
862                 case BC_RGB888:
863                         POLAR_MACRO(unsigned char, 0xff, 3, 0x0)
864                         break;
865                 case BC_RGBA8888:
866                         POLAR_MACRO(unsigned char, 0xff, 4, 0x0)
867                         break;
868                 case BC_RGB161616:
869                         POLAR_MACRO(uint16_t, 0xffff, 3, 0x0)
870                         break;
871                 case BC_RGBA16161616:
872                         POLAR_MACRO(uint16_t, 0xffff, 4, 0x0)
873                         break;
874                 case BC_YUV888:
875                         POLAR_MACRO(unsigned char, 0xff, 3, 0x80)
876                         break;
877                 case BC_YUVA8888:
878                         POLAR_MACRO(unsigned char, 0xff, 4, 0x80)
879                         break;
880                 case BC_YUV161616:
881                         POLAR_MACRO(uint16_t, 0xffff, 3, 0x8000)
882                         break;
883                 case BC_YUVA16161616:
884                         POLAR_MACRO(uint16_t, 0xffff, 4, 0x8000)
885                         break;
886         }
887 }
888
889
890
891
892 PolarEngine::PolarEngine(PolarEffect *plugin, int cpus)
893  : LoadServer(cpus, cpus)
894 {
895         this->plugin = plugin;
896 }
897
898 void PolarEngine::init_packages()
899 {
900         for(int i = 0; i < LoadServer::get_total_packages(); i++)
901         {
902                 PolarPackage *pkg = (PolarPackage*)get_package(i);
903                 pkg->row1 = plugin->input->get_h() * i / LoadServer::get_total_packages();
904                 pkg->row2 = plugin->input->get_h() * (i + 1) / LoadServer::get_total_packages();
905         }
906 }
907
908 LoadClient* PolarEngine::new_client()
909 {
910         return new PolarUnit(plugin, this);
911 }
912
913 LoadPackage* PolarEngine::new_package()
914 {
915         return new PolarPackage;
916 }
917
918
919