Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.1 / plugins / dissolve / dissolve.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 "dissolve.h"
23 #include "edl.inc"
24 #include "language.h"
25 #include "overlayframe.h"
26 #include "vframe.h"
27
28 #include <string.h>
29
30 PluginClient* new_plugin(PluginServer *server)
31 {
32         return new DissolveMain(server);
33 }
34
35
36
37
38
39 DissolveMain::DissolveMain(PluginServer *server)
40  : PluginVClient(server)
41 {
42         overlayer = 0;
43 }
44
45 DissolveMain::~DissolveMain()
46 {
47         delete overlayer;
48 }
49
50 const char* DissolveMain::plugin_title() { return _("Dissolve"); }
51 int DissolveMain::is_video() { return 1; }
52 int DissolveMain::is_transition() { return 1; }
53 int DissolveMain::uses_gui() { return 0; }
54
55
56
57 int DissolveMain::process_realtime(VFrame *incoming, VFrame *outgoing)
58 {
59         fade = (float)PluginClient::get_source_position() / 
60                         PluginClient::get_total_len();
61
62 // Use hardware
63         if(get_use_opengl())
64         {
65                 run_opengl();
66                 return 0;
67         }
68
69 // Use software
70         if(!overlayer) overlayer = new OverlayFrame(get_project_smp() + 1);
71
72
73 // There is a problem when dissolving from a big picture to a small picture.
74 // In order to make it dissolve correctly, we have to manually decrese alpha of big picture.
75         switch (outgoing->get_color_model())
76         {
77                 case BC_RGBA8888:
78                 case BC_YUVA8888:
79                 {
80                         uint8_t** data_rows = (uint8_t **)outgoing->get_rows();
81                         int w = outgoing->get_w();
82                         int h = outgoing->get_h(); 
83                         for(int i = 0; i < h; i++) 
84                         {
85                                 uint8_t* alpha_chan = data_rows[i] + 3; 
86                                 for(int j = 0; j < w; j++) 
87                                 {
88                                         *alpha_chan = (uint8_t) (*alpha_chan * (1-fade));
89                                         alpha_chan+=4;
90                                 }
91                         }
92                         break;
93                 }
94                 case BC_YUVA16161616:
95                 {
96                         uint16_t** data_rows = (uint16_t **)outgoing->get_rows();
97                         int w = outgoing->get_w();
98                         int h = outgoing->get_h(); 
99                         for(int i = 0; i < h; i++)
100                         { 
101                                 uint16_t* alpha_chan = data_rows[i] + 3; // 3 since this is uint16_t
102                                 for(int j = 0; j < w; j++) 
103                                 {
104                                         *alpha_chan = (uint16_t)(*alpha_chan * (1-fade));
105                                         alpha_chan += 8;
106                                 } 
107                         }
108                         break;
109                 }
110                 case BC_RGBA_FLOAT:
111                 {
112                         float** data_rows = (float **)outgoing->get_rows();
113                         int w = outgoing->get_w();
114                         int h = outgoing->get_h(); 
115                         for(int i = 0; i < h; i++) 
116                         { 
117                                 float* alpha_chan = data_rows[i] + 3; // 3 since this is floats 
118                                 for(int j = 0; j < w; j++) 
119                                 {
120                                         *alpha_chan = *alpha_chan * (1-fade);
121                                         alpha_chan += sizeof(float);
122                                 } 
123                         }
124                         break;
125                 }
126                 default:
127                         break;
128         }
129
130
131         overlayer->overlay(outgoing, 
132                 incoming, 
133                 0, 
134                 0, 
135                 incoming->get_w(),
136                 incoming->get_h(),
137                 0,
138                 0,
139                 incoming->get_w(),
140                 incoming->get_h(),
141                 fade,
142                 TRANSFER_NORMAL,
143                 NEAREST_NEIGHBOR);
144
145         return 0;
146 }
147
148 int DissolveMain::handle_opengl()
149 {
150 #ifdef HAVE_GL
151
152 // Read images from RAM
153         get_input()->to_texture();
154         get_output()->to_texture();
155
156 // Create output pbuffer
157         get_output()->enable_opengl();
158
159         VFrame::init_screen(get_output()->get_w(), get_output()->get_h());
160
161 // Enable output texture
162         get_output()->bind_texture(0);
163 // Draw output texture
164         glDisable(GL_BLEND);
165         glColor4f(1, 1, 1, 1);
166         get_output()->draw_texture();
167
168 // Draw input texture
169         get_input()->bind_texture(0);
170         glEnable(GL_BLEND);
171         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
172         glColor4f(1, 1, 1, fade);
173         get_input()->draw_texture();
174
175
176         glDisable(GL_BLEND);
177         get_output()->set_opengl_state(VFrame::SCREEN);
178
179
180 #endif
181         return 0;
182 }
183
184
185