no longer need ffmpeg patch0 which was for Termux
[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         xS(330),
239         yS(122),
240         xS(330),
241         yS(122),
242         0)
243 {
244         this->plugin = plugin;
245 }
246
247 void PolarWindow::create_objects()
248 {
249         int xs10 = xS(10), xs50 = xS(50);
250         int ys10 = yS(10), ys40 = yS(40);
251         int x = xs10, y = ys10, x1 = x + xs50;
252         int x2 = 0; int clrBtn_w = xs50;
253
254         add_subwindow(new BC_Title(x, y, _("Depth:")));
255         add_subwindow(depth = new PolarDepth(plugin, x1, y));
256         x2 = x1 + depth->get_w() + xs10;
257         add_subwindow(depthClr = new PolarSliderClr(plugin, this, x2, y, clrBtn_w, RESET_DEPTH));
258
259         y += ys40;
260         add_subwindow(new BC_Title(x, y, _("Angle:")));
261         add_subwindow(angle = new PolarAngle(plugin, x1, y));
262         add_subwindow(angleClr = new PolarSliderClr(plugin, this, x2, y, clrBtn_w, RESET_ANGLE));
263         y += ys40;
264         add_subwindow(reset = new PolarReset(plugin, this, x, y));
265
266         show_window();
267         flush();
268 }
269
270 // for Reset button
271 void PolarWindow::update_gui(int clear)
272 {
273         switch(clear) {
274                 case RESET_DEPTH : depth->update(plugin->config.depth);
275                         break;
276                 case RESET_ANGLE : angle->update(plugin->config.angle);
277                         break;
278                 case RESET_ALL :
279                 default:
280                         depth->update(plugin->config.depth);
281                         angle->update(plugin->config.angle);
282                         break;
283         }
284 }
285
286
287
288
289
290 PolarDepth::PolarDepth(PolarEffect *plugin, int x, int y)
291  : BC_FSlider(x,
292                 y,
293                 0,
294                 xS(200),
295                 yS(200),
296                 (float)1,
297                 (float)100,
298                 plugin->config.depth)
299 {
300         this->plugin = plugin;
301 }
302 int PolarDepth::handle_event()
303 {
304         plugin->config.depth = get_value();
305         plugin->send_configure_change();
306         return 1;
307 }
308
309
310
311
312
313 PolarAngle::PolarAngle(PolarEffect *plugin, int x, int y)
314  : BC_FSlider(x,
315                 y,
316                 0,
317                 xS(200),
318                 yS(200),
319                 (float)1,
320                 (float)360,
321                 plugin->config.angle)
322 {
323         this->plugin = plugin;
324 }
325 int PolarAngle::handle_event()
326 {
327         plugin->config.angle = get_value();
328         plugin->send_configure_change();
329         return 1;
330 }
331
332
333
334 PolarReset::PolarReset(PolarEffect *plugin, PolarWindow *window, int x, int y)
335  : BC_GenericButton(x, y, _("Reset"))
336 {
337         this->plugin = plugin;
338         this->window = window;
339 }
340 PolarReset::~PolarReset()
341 {
342 }
343 int PolarReset::handle_event()
344 {
345         plugin->config.reset(RESET_ALL);
346         window->update_gui(RESET_ALL);
347         plugin->send_configure_change();
348         return 1;
349 }
350
351
352 PolarSliderClr::PolarSliderClr(PolarEffect *plugin, PolarWindow *window, int x, int y, int w, int clear)
353  : BC_Button(x, y, w, plugin->get_theme()->get_image_set("reset_button"))
354 {
355         this->plugin = plugin;
356         this->window = window;
357         this->clear = clear;
358 }
359 PolarSliderClr::~PolarSliderClr()
360 {
361 }
362 int PolarSliderClr::handle_event()
363 {
364         // clear==1 ==> Depth slider
365         // clear==2 ==> Angle slider
366         plugin->config.reset(clear);
367         window->update_gui(clear);
368         plugin->send_configure_change();
369         return 1;
370 }
371
372
373
374
375 PolarEffect::PolarEffect(PluginServer *server)
376  : PluginVClient(server)
377 {
378         need_reconfigure = 1;
379         temp_frame = 0;
380         engine = 0;
381
382 }
383
384 PolarEffect::~PolarEffect()
385 {
386
387         if(temp_frame) delete temp_frame;
388         if(engine) delete engine;
389 }
390
391
392
393 const char* PolarEffect::plugin_title() { return N_("Polar"); }
394 int PolarEffect::is_realtime() { return 1; }
395
396
397
398
399 NEW_WINDOW_MACRO(PolarEffect, PolarWindow)
400
401 void PolarEffect::update_gui()
402 {
403         if(thread)
404         {
405                 load_configuration();
406                 thread->window->lock_window();
407                 ((PolarWindow*)thread->window)->angle->update(config.angle);
408                 ((PolarWindow*)thread->window)->depth->update(config.depth);
409                 thread->window->unlock_window();
410         }
411 }
412
413 LOAD_CONFIGURATION_MACRO(PolarEffect, PolarConfig)
414
415
416
417 void PolarEffect::save_data(KeyFrame *keyframe)
418 {
419         FileXML output;
420
421 // cause data to be stored directly in text
422         output.set_shared_output(keyframe->xbuf);
423         output.tag.set_title("POLAR");
424         output.tag.set_property("DEPTH", config.depth);
425         output.tag.set_property("ANGLE", config.angle);
426         output.append_tag();
427         output.tag.set_title("/POLAR");
428         output.append_tag();
429         output.append_newline();
430         output.terminate_string();
431 }
432
433 void PolarEffect::read_data(KeyFrame *keyframe)
434 {
435         FileXML input;
436
437         input.set_shared_input(keyframe->xbuf);
438
439         while(!input.read_tag())
440         {
441                 if(input.tag.title_is("POLAR"))
442                 {
443                         config.depth = input.tag.get_property("DEPTH", config.depth);
444                         config.angle = input.tag.get_property("ANGLE", config.angle);
445                 }
446         }
447 }
448
449 int PolarEffect::process_realtime(VFrame *input, VFrame *output)
450 {
451         need_reconfigure |= load_configuration();
452
453         this->input = input;
454         this->output = output;
455
456         if(EQUIV(config.depth, 0) || EQUIV(config.angle, 0))
457         {
458                 if(input->get_rows()[0] != output->get_rows()[0])
459                         output->copy_from(input);
460         }
461         else
462         {
463                 if(input->get_rows()[0] == output->get_rows()[0])
464                 {
465                         if(!temp_frame)
466                                 temp_frame = new VFrame(input->get_w(), input->get_h(),
467                                         input->get_color_model(), 0);
468                         temp_frame->copy_from(input);
469                         this->input = temp_frame;
470                 }
471
472
473                 if(!engine) engine = new PolarEngine(this, PluginClient::smp + 1);
474
475                 engine->process_packages();
476         }
477         return 0;
478 }
479
480
481
482
483
484 PolarPackage::PolarPackage()
485  : LoadPackage()
486 {
487 }
488
489
490
491
492 PolarUnit::PolarUnit(PolarEffect *plugin, PolarEngine *server)
493  : LoadClient(server)
494 {
495         this->plugin = plugin;
496 }
497
498
499 static int calc_undistorted_coords(int wx,
500                          int wy,
501                          int w,
502                          int h,
503                          float depth,
504                          double angle,
505                          int polar_to_rectangular,
506                          int backwards,
507                          int inverse,
508                          double cen_x,
509                          double cen_y,
510                          double &x,
511                          double &y)
512 {
513         int inside;
514         double phi, phi2;
515         double xx, xm, ym, yy;
516         int xdiff, ydiff;
517         double r;
518         double m;
519         double xmax, ymax, rmax;
520         double x_calc, y_calc;
521         double xi, yi;
522         double circle, angl, t;
523         int x1, x2, y1, y2;
524
525 /* initialize */
526
527         phi = 0.0;
528         r = 0.0;
529
530         x1 = 0;
531         y1 = 0;
532         x2 = w;
533         y2 = h;
534         xdiff = x2 - x1;
535         ydiff = y2 - y1;
536         xm = xdiff / 2.0;
537         ym = ydiff / 2.0;
538         circle = depth;
539         angle = angle;
540         angl = (double)angle / 180.0 * M_PI;
541
542     if(polar_to_rectangular)
543     {
544         if(wx >= cen_x)
545                 {
546                         if(wy > cen_y)
547                 {
548                         phi = M_PI -
549                                         atan(((double)(wx - cen_x)) /
550                                         ((double)(wy - cen_y)));
551                         r   = sqrt(SQR(wx - cen_x) +
552                                         SQR(wy - cen_y));
553                 }
554                         else
555                         if(wy < cen_y)
556                 {
557                         phi = atan(((double)(wx - cen_x)) /
558                                         ((double)(cen_y - wy)));
559                         r   = sqrt(SQR(wx - cen_x) +
560                                         SQR(cen_y - wy));
561                 }
562                         else
563                 {
564                         phi = M_PI / 2;
565                         r   = wx - cen_x;
566                 }
567                 }
568         else
569                 if(wx < cen_x)
570                 {
571                         if(wy < cen_y)
572                 {
573                         phi = 2 * M_PI -
574                                         atan(((double)(cen_x -wx)) /
575                                     ((double)(cen_y - wy)));
576                         r   = sqrt(SQR(cen_x - wx) +
577                                         SQR(cen_y - wy));
578                 }
579                         else
580                         if(wy > cen_y)
581                 {
582                         phi = M_PI +
583                                         atan(((double)(cen_x - wx)) /
584                                         ((double)(wy - cen_y)));
585                         r   = sqrt(SQR(cen_x - wx) +
586                                         SQR(wy - cen_y));
587                 }
588                         else
589                 {
590                         phi = 1.5 * M_PI;
591                         r   = cen_x - wx;
592                 }
593                 }
594         if (wx != cen_x)
595                 {
596                         m = fabs(((double)(wy - cen_y)) /
597                                 ((double)(wx - cen_x)));
598                 }
599         else
600                 {
601                     m = 0;
602                 }
603
604         if(m <= ((double)(y2 - y1) /
605                         (double)(x2 - x1)))
606                 {
607                         if(wx == cen_x)
608                 {
609                         xmax = 0;
610                         ymax = cen_y - y1;
611                 }
612                         else
613                 {
614                         xmax = cen_x - x1;
615                         ymax = m * xmax;
616                 }
617                 }
618         else
619                 {
620                         ymax = cen_y - y1;
621                         xmax = ymax / m;
622                 }
623
624         rmax = sqrt((double)(SQR(xmax) + SQR(ymax)));
625
626         t = ((cen_y - y1) < (cen_x - x1)) ? (cen_y - y1) : (cen_x - x1);
627         rmax = (rmax - t) / 100 * (100 - circle) + t;
628
629         phi = fmod(phi + angl, 2 * M_PI);
630
631         if(backwards)
632                         x_calc = x2 - 1 - (x2 - x1 - 1) / (2 * M_PI) * phi;
633         else
634                         x_calc = (x2 - x1 - 1) / (2 * M_PI) * phi + x1;
635
636         if(inverse)
637                         y_calc = (y2 - y1) / rmax * r + y1;
638         else
639                         y_calc = y2 - (y2 - y1) / rmax * r;
640
641         xi = (int)(x_calc + 0.5);
642         yi = (int)(y_calc + 0.5);
643
644         if(WITHIN(0, xi, w - 1) && WITHIN(0, yi, h - 1))
645                 {
646                         x = x_calc;
647                         y = y_calc;
648
649                         inside = 1;
650                 }
651         else
652                 {
653                         inside = 0;
654                 }
655     }
656         else
657     {
658         if(backwards)
659                         phi = (2 * M_PI) * (x2 - wx) / xdiff;
660         else
661                         phi = (2 * M_PI) * (wx - x1) / xdiff;
662
663         phi = fmod (phi + angl, 2 * M_PI);
664
665         if(phi >= 1.5 * M_PI)
666                         phi2 = 2 * M_PI - phi;
667         else
668                 if (phi >= M_PI)
669                         phi2 = phi - M_PI;
670                 else
671                 if(phi >= 0.5 * M_PI)
672                 phi2 = M_PI - phi;
673                 else
674                 phi2 = phi;
675
676         xx = tan (phi2);
677         if(xx != 0)
678                         m = (double)1.0 / xx;
679         else
680                         m = 0;
681
682         if(m <= ((double)(ydiff) / (double)(xdiff)))
683                 {
684                         if(phi2 == 0)
685                 {
686                         xmax = 0;
687                         ymax = ym - y1;
688                 }
689                         else
690                 {
691                         xmax = xm - x1;
692                         ymax = m * xmax;
693                 }
694                 }
695         else
696                 {
697                         ymax = ym - y1;
698                         xmax = ymax / m;
699                 }
700
701         rmax = sqrt((double)(SQR(xmax) + SQR(ymax)));
702
703         t = ((ym - y1) < (xm - x1)) ? (ym - y1) : (xm - x1);
704
705         rmax = (rmax - t) / 100.0 * (100 - circle) + t;
706
707         if(inverse)
708                         r = rmax * (double)((wy - y1) / (double)(ydiff));
709         else
710                         r = rmax * (double)((y2 - wy) / (double)(ydiff));
711
712         xx = r * sin (phi2);
713         yy = r * cos (phi2);
714
715         if(phi >= 1.5 * M_PI)
716                 {
717                         x_calc = (double)xm - xx;
718                         y_calc = (double)ym - yy;
719                 }
720         else
721                 if(phi >= M_PI)
722                 {
723                 x_calc = (double)xm - xx;
724                 y_calc = (double)ym + yy;
725                 }
726                 else
727                 if(phi >= 0.5 * M_PI)
728             {
729                 x_calc = (double)xm + xx;
730                 y_calc = (double)ym + yy;
731             }
732                 else
733             {
734                 x_calc = (double)xm + xx;
735                 y_calc = (double)ym - yy;
736             }
737
738         xi = (int)(x_calc + 0.5);
739         yi = (int)(y_calc + 0.5);
740
741         if(WITHIN(0, xi, w - 1) &&
742                         WITHIN(0, yi, h - 1))
743                 {
744                         x = x_calc;
745                         y = y_calc;
746
747                         inside = 1;
748         }
749         else
750                 {
751                         inside = 0;
752                 }
753     }
754
755         return inside;
756 }
757
758 static double bilinear(double x, double y, double *values)
759 {
760         double m0, m1;
761         x = fmod(x, 1.0);
762         y = fmod(y, 1.0);
763
764         if(x < 0.0) x += 1.0;
765         if(y < 0.0) y += 1.0;
766
767         m0 = values[0] + x * (values[1] - values[0]);
768         m1 = values[2] + x * (values[3] - values[2]);
769         return m0 + y * (m1 - m0);
770 }
771
772 #define GET_PIXEL(x, y, components, input_rows) \
773         input_rows[CLIP((y), 0, ((h) - 1))] + components * CLIP((x), 0, ((w) - 1))
774
775 #define POLAR_MACRO(type, max, components, chroma_offset) \
776 { \
777         type **in_rows = (type**)plugin->input->get_rows(); \
778         type **out_rows = (type**)plugin->output->get_rows(); \
779         double values[4]; \
780  \
781         for(int y = pkg->row1; y < pkg->row2; y++) \
782         { \
783                 type *output_row = out_rows[y]; \
784  \
785                 for(int x = 0; x < w; x++) \
786                 { \
787                         type *output_pixel = output_row + x * components; \
788                         if(calc_undistorted_coords(x, \
789                                 y, \
790                                 w, \
791                                 h, \
792                                 plugin->config.depth, \
793                                 plugin->config.angle, \
794                                 plugin->config.polar_to_rectangular, \
795                                 plugin->config.backwards, \
796                                 plugin->config.invert, \
797                                 cen_x, \
798                                 cen_y, \
799                                 cx, \
800                                 cy)) \
801                         { \
802                                 type *pixel1 = GET_PIXEL((int)cx,     (int)cy,   components, in_rows); \
803                                 type *pixel2 = GET_PIXEL((int)cx + 1, (int)cy,   components, in_rows); \
804                                 type *pixel3 = GET_PIXEL((int)cx,     (int)cy + 1, components, in_rows); \
805                                 type *pixel4 = GET_PIXEL((int)cx + 1, (int)cy + 1, components, in_rows); \
806  \
807                                 values[0] = pixel1[0]; \
808                                 values[1] = pixel2[0]; \
809                                 values[2] = pixel3[0]; \
810                                 values[3] = pixel4[0]; \
811                                 output_pixel[0] = (type)bilinear(cx, cy, values); \
812  \
813                                 values[0] = pixel1[1]; \
814                                 values[1] = pixel2[1]; \
815                                 values[2] = pixel3[1]; \
816                                 values[3] = pixel4[1]; \
817                                 output_pixel[1] = (type)bilinear(cx, cy, values); \
818  \
819                                 values[0] = pixel1[2]; \
820                                 values[1] = pixel2[2]; \
821                                 values[2] = pixel3[2]; \
822                                 values[3] = pixel4[2]; \
823                                 output_pixel[2] = (type)bilinear(cx, cy, values); \
824  \
825                                 if(components == 4) \
826                                 { \
827                                         values[0] = pixel1[3]; \
828                                         values[1] = pixel2[3]; \
829                                         values[2] = pixel3[3]; \
830                                         values[3] = pixel4[3]; \
831                                         output_pixel[3] = (type)bilinear(cx, cy, values); \
832                                 } \
833                         } \
834                         else \
835                         { \
836                                 output_pixel[0] = 0; \
837                                 output_pixel[1] = chroma_offset; \
838                                 output_pixel[2] = chroma_offset; \
839                                 if(components == 4) output_pixel[3] = max; \
840                         } \
841                 } \
842         } \
843 }
844
845
846 void PolarUnit::process_package(LoadPackage *package)
847 {
848         PolarPackage *pkg = (PolarPackage*)package;
849         int w = plugin->input->get_w();
850         int h = plugin->input->get_h();
851         double cx;
852         double cy;
853         double cen_x = (double)(w - 1) / 2.0;
854         double cen_y = (double)(h - 1) / 2.0;
855
856         switch(plugin->input->get_color_model())
857         {
858                 case BC_RGB_FLOAT:
859                         POLAR_MACRO(float, 1, 3, 0x0)
860                         break;
861                 case BC_RGBA_FLOAT:
862                         POLAR_MACRO(float, 1, 4, 0x0)
863                         break;
864                 case BC_RGB888:
865                         POLAR_MACRO(unsigned char, 0xff, 3, 0x0)
866                         break;
867                 case BC_RGBA8888:
868                         POLAR_MACRO(unsigned char, 0xff, 4, 0x0)
869                         break;
870                 case BC_RGB161616:
871                         POLAR_MACRO(uint16_t, 0xffff, 3, 0x0)
872                         break;
873                 case BC_RGBA16161616:
874                         POLAR_MACRO(uint16_t, 0xffff, 4, 0x0)
875                         break;
876                 case BC_YUV888:
877                         POLAR_MACRO(unsigned char, 0xff, 3, 0x80)
878                         break;
879                 case BC_YUVA8888:
880                         POLAR_MACRO(unsigned char, 0xff, 4, 0x80)
881                         break;
882                 case BC_YUV161616:
883                         POLAR_MACRO(uint16_t, 0xffff, 3, 0x8000)
884                         break;
885                 case BC_YUVA16161616:
886                         POLAR_MACRO(uint16_t, 0xffff, 4, 0x8000)
887                         break;
888         }
889 }
890
891
892
893
894 PolarEngine::PolarEngine(PolarEffect *plugin, int cpus)
895  : LoadServer(cpus, cpus)
896 {
897         this->plugin = plugin;
898 }
899
900 void PolarEngine::init_packages()
901 {
902         for(int i = 0; i < LoadServer::get_total_packages(); i++)
903         {
904                 PolarPackage *pkg = (PolarPackage*)get_package(i);
905                 pkg->row1 = plugin->input->get_h() * i / LoadServer::get_total_packages();
906                 pkg->row2 = plugin->input->get_h() * (i + 1) / LoadServer::get_total_packages();
907         }
908 }
909
910 LoadClient* PolarEngine::new_client()
911 {
912         return new PolarUnit(plugin, this);
913 }
914
915 LoadPackage* PolarEngine::new_package()
916 {
917         return new PolarPackage;
918 }
919
920
921