add x10tv ati remote rework, android remote rework, wintv remote tweaks
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / overlaynearest.C
1 #include "overlayframe.h"
2 #include "overlaynearest.h"
3
4 /* Nearest Neighbor scale / translate / blend ********************/
5
6 NNPackage::NNPackage()
7 {
8 }
9
10 NNUnit::NNUnit(NNEngine *server)
11  : LoadClient(server)
12 {
13         this->engine = server;
14 }
15
16 NNUnit::~NNUnit()
17 {
18 }
19
20 void NNUnit::process_package(LoadPackage *package)
21 {
22         pkg = (NNPackage*)package;
23         output = engine->output;
24         input = engine->input;
25         mode = engine->mode;
26         fade = BC_CModels::has_alpha(input->get_color_model()) &&
27                 mode == TRANSFER_REPLACE ? 1.f : engine->alpha;
28
29         ox = engine->out_x1i;
30         ow = engine->out_x2i - ox;
31         ly = engine->in_lookup_y + pkg->out_row1;
32
33         switch(input->get_color_model()) {
34         case BC_RGB_FLOAT:      rgb_float();    break;
35         case BC_RGBA_FLOAT:     rgba_float();   break;
36         case BC_RGB888:         rgb888();       break;
37         case BC_YUV888:         yuv888();       break;
38         case BC_RGBA8888:       rgba8888();     break;
39         case BC_YUVA8888:       yuva8888();     break;
40         case BC_RGB161616:      rgb161616();    break;
41         case BC_YUV161616:      yuv161616();    break;
42         case BC_RGBA16161616:   rgba16161616(); break;
43         case BC_YUVA16161616:   yuva16161616();  break;
44         }
45 }
46
47 NNEngine::NNEngine(int cpus)
48  : LoadServer(cpus, cpus)
49 {
50         in_lookup_x = 0;
51         in_lookup_y = 0;
52 }
53
54 NNEngine::~NNEngine()
55 {
56         if(in_lookup_x)
57                 delete[] in_lookup_x;
58         if(in_lookup_y)
59                 delete[] in_lookup_y;
60 }
61
62 void NNEngine::init_packages()
63 {
64         int in_w = input->get_w();
65         int in_h = input->get_h();
66         int out_w = output->get_w();
67         int out_h = output->get_h();
68
69         float in_subw = in_x2 - in_x1;
70         float in_subh = in_y2 - in_y1;
71         float out_subw = out_x2 - out_x1;
72         float out_subh = out_y2 - out_y1;
73         int first, last, count, i;
74         int components = 3;
75
76         out_x1i = rint(out_x1);
77         out_x2i = rint(out_x2);
78         if(out_x1i < 0) out_x1i = 0;
79         if(out_x1i > out_w) out_x1i = out_w;
80         if(out_x2i < 0) out_x2i = 0;
81         if(out_x2i > out_w) out_x2i = out_w;
82         int out_wi = out_x2i - out_x1i;
83         if( !out_wi ) return;
84
85         delete[] in_lookup_x;
86         in_lookup_x = new int[out_wi];
87         delete[] in_lookup_y;
88         in_lookup_y = new int[out_h];
89
90         switch(input->get_color_model()) {
91         case BC_RGBA_FLOAT:
92         case BC_RGBA8888:
93         case BC_YUVA8888:
94         case BC_RGBA16161616:
95                 components = 4;
96                 break;
97         }
98
99         first = count = 0;
100
101         for(i = out_x1i; i < out_x2i; i++) {
102                 int in = (i - out_x1 + .5) * in_subw / out_subw + in_x1;
103                 if(in < in_x1)
104                         in = in_x1;
105                 if(in > in_x2)
106                         in = in_x2;
107
108                 if(in >= 0 && in < in_w && in >= in_x1 && i >= 0 && i < out_w) {
109                         if(count == 0) {
110                                 first = i;
111                                 in_lookup_x[0] = in * components;
112                         }
113                         else {
114                                 in_lookup_x[count] = (in-last)*components;
115                         }
116                         last = in;
117                         count++;
118                 }
119                 else if(count)
120                         break;
121         }
122         out_x1i = first;
123         out_x2i = first + count;
124         first = count = 0;
125
126         for(i = out_y1; i < out_y2; i++) {
127                 int in = (i - out_y1+.5) * in_subh / out_subh + in_y1;
128                 if(in < in_y1) in = in_y1;
129                 if(in > in_y2) in = in_y2;
130                 if(in >= 0 && in < in_h && i >= 0 && i < out_h) {
131                         if(count == 0) first = i;
132                         in_lookup_y[i] = in;
133                         count++;
134                 }
135                 else if(count)
136                         break;
137         }
138         out_y1 = first;
139         out_y2 = first + count;
140
141         int rows = count;
142         int pkgs = get_total_packages();
143         int row1 = out_y1, row2 = row1;
144         for(int i = 0; i < pkgs; row1=row2 ) {
145                 NNPackage *package = (NNPackage*)get_package(i);
146                 row2 = ++i * rows / pkgs + out_y1;
147                 package->out_row1 = row1;
148                 package->out_row2 = row2;
149         }
150 }
151
152 LoadClient* NNEngine::new_client()
153 {
154         return new NNUnit(this);
155 }
156
157 LoadPackage* NNEngine::new_package()
158 {
159         return new NNPackage;
160 }
161
162