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