add auto zoombar/status color, fix 3 batchrender boobies, rotate plugin tweaks, add...
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / puzzleobj / puzzleobj.C
1 /*
2  * CINELERRA
3  * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  * 
19  */
20
21 #include "clip.h"
22 #include "filexml.h"
23 #include "puzzleobj.h"
24 #include "puzzleobjwindow.h"
25 #include "language.h"
26 #include "mutex.h"
27
28 REGISTER_PLUGIN(PuzzleObj)
29
30
31 PuzzleObjConfig::PuzzleObjConfig()
32 {
33         pixels = 400;
34         iterations = 10;
35 }
36
37 int PuzzleObjConfig::equivalent(PuzzleObjConfig &that)
38 {
39         return 1;
40 }
41
42 void PuzzleObjConfig::copy_from(PuzzleObjConfig &that)
43 {
44 }
45
46 void PuzzleObjConfig::interpolate( PuzzleObjConfig &prev, PuzzleObjConfig &next, 
47         long prev_frame, long next_frame, long current_frame)
48 {
49         copy_from(next);
50 }
51
52 void PuzzleObjConfig::limits()
53 {
54 }
55
56
57 PuzzleObj::PuzzleObj(PluginServer *server)
58  : PluginVClient(server)
59 {
60         ss_width = 0;  ss_height = 0;  ss_channels = 0;
61         ss_pixels = 0; ss_levels = 0;  ss_prior = 0;
62         ss_hist_bins = 0;
63 }
64
65 PuzzleObj::~PuzzleObj()
66 {
67 }
68
69 const char* PuzzleObj::plugin_title() { return N_("PuzzleObj"); }
70 int PuzzleObj::is_realtime() { return 1; }
71
72 NEW_WINDOW_MACRO(PuzzleObj, PuzzleObjWindow);
73 LOAD_CONFIGURATION_MACRO(PuzzleObj, PuzzleObjConfig)
74
75 void PuzzleObj::save_data(KeyFrame *keyframe)
76 {
77         FileXML output;
78
79 // cause data to be stored directly in text
80         output.set_shared_output(keyframe->xbuf);
81         output.tag.set_title("PUZZLEOBJ");
82         output.tag.set_property("PIXELS", config.pixels);
83         output.tag.set_property("ITERATIONS", config.iterations);
84         output.append_tag();
85         output.append_newline();
86         output.tag.set_title("/PUZZLEOBJ");
87         output.append_tag();
88         output.append_newline();
89         output.terminate_string();
90 }
91
92 void PuzzleObj::read_data(KeyFrame *keyframe)
93 {
94         FileXML input;
95         input.set_shared_input(keyframe->xbuf);
96
97         int result = 0;
98         while( !(result = input.read_tag()) ) {
99                 if( input.tag.title_is("PUZZLEOBJ") ) {
100                         config.pixels     = input.tag.get_property("PIXELS", config.pixels);
101                         config.iterations = input.tag.get_property("ITERATIONS", config.iterations);
102                         config.limits();
103                 }
104                 else if( input.tag.title_is("/PUZZLEOBJ") )
105                         result = 1;
106         }
107 }
108
109 void PuzzleObj::update_gui()
110 {
111         if( !thread ) return;
112         if( !load_configuration() ) return;
113         thread->window->lock_window("PuzzleObj::update_gui");
114         PuzzleObjWindow *window = (PuzzleObjWindow*)thread->window;
115         window->unlock_window();
116 }
117
118 void PuzzleObj::to_mat(Mat &mat, int mcols, int mrows,
119         VFrame *inp, int ix,int iy, int mcolor_model)
120 {
121         int mcomp = BC_CModels::components(mcolor_model);
122         int mbpp = BC_CModels::calculate_pixelsize(mcolor_model);
123         int psz = mbpp / mcomp;
124         int mdepth = psz < 2 ? CV_8U : psz < 4 ? CV_16U : CV_32F;
125         if( mat.dims != 2 || mat.depth() != mdepth || mat.channels() != mcomp ||
126             mat.cols != mcols || mat.rows != mrows ) {
127                 mat.release();
128         }
129         if( mat.empty() ) {
130                 int type = CV_MAKETYPE(mdepth, mcomp);
131                 mat.create(mrows, mcols, type);
132         }
133         uint8_t *mat_rows[mrows];
134         for( int y=0; y<mrows; ++y ) mat_rows[y] = mat.ptr(y);
135         uint8_t **inp_rows = inp->get_rows();
136         int ibpl = inp->get_bytes_per_line(), mbpl = mcols * mbpp;
137         int icolor_model = inp->get_color_model();
138         BC_CModels::transfer(mat_rows, mcolor_model, 0,0, mcols,mrows, mbpl,
139                 inp_rows, icolor_model, ix,iy, mcols,mrows, ibpl, 0);
140 //      VFrame vfrm(mat_rows[0], -1, mcols,mrows, mcolor_model, mat_rows[1]-mat_rows[0]);
141 //      static int vfrm_no = 0; char vfn[64]; sprintf(vfn,"/tmp/idat/%06d.png", vfrm_no++);
142 //      vfrm.write_png(vfn);
143 }
144
145 int PuzzleObj::process_buffer(VFrame *frame, int64_t start_position, double frame_rate)
146 {
147
148         //int need_reconfigure =
149         load_configuration();
150         input = get_input(0);
151         output = get_output(0);
152         width = input->get_w();
153         height = input->get_h();
154         color_model = input->get_color_model();
155         VFrame *iframe = input;
156         read_frame(iframe, 0, start_position, frame_rate, 0);
157         int cv_color_model = BC_RGB888;
158         if( color_model != cv_color_model ) {
159                 iframe = new_temp(width,height, cv_color_model);
160                 iframe->transfer_from(input);
161         }
162         int prior = 2;
163         int levels = 4;
164         int hist_bins = 5;
165         int channels = BC_CModels::components(cv_color_model);
166
167 // load next image
168         to_mat(next_img, width,height, iframe, 0,0, cv_color_model);
169         Mat img; //, img1;
170         cvtColor(next_img, img, COLOR_RGB2HSV);
171         if( !sseeds.empty() &&
172             ( ss_width != width || ss_height != height || ss_channels != channels ||
173             ss_pixels != config.pixels || ss_levels != levels || ss_prior != prior ||
174             ss_hist_bins != hist_bins ) )
175                 sseeds.release();
176         if( sseeds.empty() )
177                 sseeds = ximgproc::createSuperpixelSEEDS(
178                         ss_width=width, ss_height=height, ss_channels=channels,
179                         ss_pixels=config.pixels, ss_levels=levels, ss_prior=prior,
180                         ss_hist_bins=hist_bins, false);
181         sseeds->iterate(img, config.iterations);
182 //      sseeds->getLabels(img1);
183         sseeds->getLabelContourMask(img, false);
184         uint8_t **irows = input->get_rows();
185         int ibpp = BC_CModels::calculate_pixelsize(color_model);
186         uint8_t **orows = output->get_rows();
187         int obpp = BC_CModels::calculate_pixelsize(color_model);
188         if( BC_CModels::is_float(color_model) ) {
189                 for( int y=0; y<height; ++y ) {
190                         uint8_t *rp = img.ptr(y);
191                         float *ip = (float*)irows[y], *op = (float*)orows[y];
192                         for( int x=0; x<width; ++x,++rp ) {
193                                 if( *rp ) { op[0] = 1.0f; op[1] = 1.0f; op[2] = 1.0f; }
194                                 else { op[0] = ip[0];  op[1] = ip[1];  op[2] = ip[2]; }
195                                 ip = (float*)((char*)ip + ibpp);
196                                 op = (float*)((char*)op + obpp);
197                         }
198                 }
199         }
200         else if( BC_CModels::is_yuv(color_model) ) {
201                 for( int y=0; y<height; ++y ) {
202                         uint8_t *rp = img.ptr(y), *ip = irows[y], *op = orows[y];
203                         for( int x=0; x<width; ++x,++rp ) {
204                                 if( *rp ) { op[0] = 0xff; op[1] = 0x80; op[2] = 0x80; }
205                                 else { op[0] = ip[0];  op[1] = ip[1];  op[2] = ip[2]; }
206                                 ip += ibpp;  op += obpp;
207                         }
208                 }
209         }
210         else {
211                 for( int y=0; y<height; ++y ) {
212                         uint8_t *rp = img.ptr(y), *ip = irows[y], *op = orows[y];
213                         for( int x=0; x<width; ++x,++rp ) {
214                                 if( *rp ) { op[0] = 0xff; op[1] = 0xff; op[2] = 0xff; }
215                                 else { op[0] = ip[0];  op[1] = ip[1];  op[2] = ip[2]; }
216                                 ip += ibpp;  op += obpp;
217                         }
218                 }
219         }
220         return 0;
221 }
222