add missing GPL information in guicast program files
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / fadeengine.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 "fadeengine.h"
23 #include "vframe.h"
24
25 #include <stdint.h>
26
27
28
29
30
31
32
33
34
35 FadeUnit::FadeUnit(FadeEngine *server)
36  : LoadClient(server)
37 {
38         this->engine = server;
39 }
40
41 FadeUnit::~FadeUnit()
42 {
43 }
44
45
46 #define APPLY_FADE(equivalent, \
47         input_rows,  \
48         output_rows,  \
49         max,  \
50         type,  \
51         temp_type,  \
52         chroma_zero,  \
53         components) \
54 { \
55         temp_type opacity = (temp_type)(alpha * max); \
56         temp_type transparency = (temp_type)(max - opacity); \
57         temp_type product = (temp_type) (chroma_zero * transparency); \
58  \
59         for(int i = row1; i < row2; i++) \
60         { \
61                 type *in_row = (type*)input_rows[i]; \
62                 type *out_row = (type*)output_rows[i]; \
63  \
64                 for(int j = 0; j < width; j++, out_row += components, in_row += components) \
65                 { \
66                         if(components == 3) \
67                         { \
68                                 out_row[0] =  \
69                                         (type)((temp_type)in_row[0] * opacity / max); \
70                                 out_row[1] =  \
71                                         (type)(((temp_type)in_row[1] * opacity +  \
72                                                 product) / max); \
73                                 out_row[2] =  \
74                                         (type)(((temp_type)in_row[2] * opacity +  \
75                                                 product) / max); \
76                         } \
77                         else \
78                         { \
79                                 if(!equivalent) \
80                                 { \
81                                         out_row[0] = in_row[0]; \
82                                         out_row[1] = in_row[1]; \
83                                         out_row[2] = in_row[2]; \
84                                 } \
85  \
86                                 if(in_row[3] == max) \
87                                         out_row[3] = opacity; \
88                                 else \
89                                 out_row[3] =  \
90                                         (type)((temp_type)in_row[3] * opacity / max); \
91                         } \
92                 } \
93         } \
94 }
95
96
97
98 void FadeUnit::process_package(LoadPackage *package)
99 {
100         FadePackage *pkg = (FadePackage*)package;
101         VFrame *output = engine->output;
102         VFrame *input = engine->input;
103         float alpha = engine->alpha;
104         int row1 = pkg->out_row1;
105         int row2 = pkg->out_row2;
106         unsigned char **in_rows = input->get_rows();
107         unsigned char **out_rows = output->get_rows();
108         int width = input->get_w();
109
110         if(input->get_rows()[0] == output->get_rows()[0])
111         {
112                 switch(input->get_color_model())
113                 {
114                         case BC_RGB888:
115                                 APPLY_FADE(1, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x0, 3);
116                                 break;
117                         case BC_RGBA8888:
118                                 APPLY_FADE(1, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x0, 4);
119                                 break;
120                         case BC_RGB_FLOAT:
121                                 APPLY_FADE(1, out_rows, in_rows, 1.0, float, float, 0x0, 3);
122                                 break;
123                         case BC_RGBA_FLOAT:
124                                 APPLY_FADE(1, out_rows, in_rows, 1.0, float, float, 0x0, 4);
125                                 break;
126                         case BC_RGB161616:
127                                 APPLY_FADE(1, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x0, 3);
128                                 break;
129                         case BC_RGBA16161616:
130                                 APPLY_FADE(1, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x0, 4);
131                                 break;
132                         case BC_YUV888:
133                                 APPLY_FADE(1, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x80, 3);
134                                 break;
135                         case BC_YUVA8888:
136                                 APPLY_FADE(1, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x80, 4);
137                                 break;
138                         case BC_YUV161616:
139                                 APPLY_FADE(1, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x8000, 3);
140                                 break;
141                         case BC_YUVA16161616:
142                                 APPLY_FADE(1, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x8000, 4);
143                                 break;
144                 }
145         }
146         else
147         {
148                 switch(input->get_color_model())
149                 {
150                         case BC_RGB888:
151                                 APPLY_FADE(0, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x0, 3);
152                                 break;
153                         case BC_RGBA8888:
154                                 APPLY_FADE(0, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x0, 4);
155                                 break;
156                         case BC_RGB_FLOAT:
157                                 APPLY_FADE(0, out_rows, in_rows, 1.0, float, float, 0x0, 3);
158                                 break;
159                         case BC_RGBA_FLOAT:
160                                 APPLY_FADE(0, out_rows, in_rows, 1.0, float, float, 0x0, 4);
161                                 break;
162                         case BC_RGB161616:
163                                 APPLY_FADE(0, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x0, 3);
164                                 break;
165                         case BC_RGBA16161616:
166                                 APPLY_FADE(0, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x0, 4);
167                                 break;
168                         case BC_YUV888:
169                                 APPLY_FADE(0, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x80, 3);
170                                 break;
171                         case BC_YUVA8888:
172                                 APPLY_FADE(0, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x80, 4);
173                                 break;
174                         case BC_YUV161616:
175                                 APPLY_FADE(0, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x8000, 3);
176                                 break;
177                         case BC_YUVA16161616:
178                                 APPLY_FADE(0, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x8000, 4);
179                                 break;
180                 }
181         }
182 }
183
184
185
186
187
188
189
190
191
192 FadeEngine::FadeEngine(int cpus)
193  : LoadServer(cpus, cpus)
194 {
195 }
196
197 FadeEngine::~FadeEngine()
198 {
199 }
200
201 void FadeEngine::do_fade(VFrame *output, VFrame *input, float alpha)
202 {
203         this->output = output;
204         this->input = input;
205         this->alpha = alpha;
206
207 // Sanity
208         if(alpha == 1)
209                 output->copy_from(input);
210         else
211                 process_packages();
212 }
213
214
215 void FadeEngine::init_packages()
216 {
217         for(int i = 0; i < get_total_packages(); i++)
218         {
219                 FadePackage *package = (FadePackage*)get_package(i);
220                 package->out_row1 = input->get_h() * i / get_total_packages();
221                 package->out_row2 = input->get_h() * (i + 1) / get_total_packages();
222         }
223 }
224
225 LoadClient* FadeEngine::new_client()
226 {
227         return new FadeUnit(this);
228 }
229
230 LoadPackage* FadeEngine::new_package()
231 {
232         return new FadePackage;
233 }
234
235
236 FadePackage::FadePackage()
237 {
238 }
239