r864: Merge 2.1:
[cinelerra_cv/ct.git] / plugins / rgb601 / rgb601.C
blob7eb889e975be8d2549845ac43c0177d9e2181522
1 #include "clip.h"
2 #include "colormodels.h"
3 #include "filexml.h"
4 #include "language.h"
5 #include "picon_png.h"
6 #include "rgb601.h"
7 #include "rgb601window.h"
9 #include <stdio.h>
10 #include <string.h>
13 REGISTER_PLUGIN(RGB601Main)
18 RGB601Config::RGB601Config()
20         direction = 0;
23 RGB601Main::RGB601Main(PluginServer *server)
24  : PluginVClient(server)
26         PLUGIN_CONSTRUCTOR_MACRO
29 RGB601Main::~RGB601Main()
31         PLUGIN_DESTRUCTOR_MACRO
34 char* RGB601Main::plugin_title() { return N_("RGB - 601"); }
35 int RGB601Main::is_realtime() { return 1; }
38 SHOW_GUI_MACRO(RGB601Main, RGB601Thread)
40 SET_STRING_MACRO(RGB601Main)
42 RAISE_WINDOW_MACRO(RGB601Main)
44 NEW_PICON_MACRO(RGB601Main)
46 void RGB601Main::update_gui()
48         if(thread)
49         {
50                 load_configuration();
51                 thread->window->lock_window();
52                 thread->window->forward->update(config.direction == 1);
53                 thread->window->reverse->update(config.direction == 2);
54                 thread->window->unlock_window();
55         }
58 int RGB601Main::load_defaults()
60         char directory[1024], string[1024];
61 // set the default directory
62         sprintf(directory, "%srgb601.rc", BCASTDIR);
64 // load the defaults
65         defaults = new BC_Hash(directory);
66         defaults->load();
68         config.direction = defaults->get("DIRECTION", config.direction);
69         return 0;
72 int RGB601Main::save_defaults()
74         defaults->update("DIRECTION", config.direction);
75         defaults->save();
76         return 0;
79 void RGB601Main::load_configuration()
81         KeyFrame *prev_keyframe;
83         prev_keyframe = get_prev_keyframe(get_source_position());
84 // Must also switch between interpolation between keyframes and using first keyframe
85         read_data(prev_keyframe);
89 void RGB601Main::save_data(KeyFrame *keyframe)
91         FileXML output;
93 // cause data to be stored directly in text
94         output.set_shared_string(keyframe->data, MESSAGESIZE);
95         output.tag.set_title("RGB601");
96         output.tag.set_property("DIRECTION", config.direction);
97         output.append_tag();
98         output.terminate_string();
101 void RGB601Main::read_data(KeyFrame *keyframe)
103         FileXML input;
105         input.set_shared_string(keyframe->data, strlen(keyframe->data));
107         int result = 0;
108         float new_threshold;
110         while(!result)
111         {
112                 result = input.read_tag();
114                 if(!result)
115                 {
116                         if(input.tag.title_is("RGB601"))
117                         {
118                                 config.direction = input.tag.get_property("DIRECTION", config.direction);
119                         }
120                 }
121         }
123         if(thread) 
124         {
125                 thread->window->update();
126         }
130 #define CREATE_TABLE(max) \
131 { \
132         for(int i = 0; i < max; i++) \
133         { \
134                 int forward_output = (int)((double)0.8588 * i + max * 0.0627 + 0.5); \
135                 int reverse_output = (int)((double)1.1644 * i - max * 0.0627 + 0.5); \
136                 forward_table[i] = CLIP(forward_output, 0, max - 1); \
137                 reverse_table[i] = CLIP(reverse_output, 0, max - 1); \
138         } \
141 void RGB601Main::create_table(VFrame *input_ptr)
143         switch(input_ptr->get_color_model())
144         {
145                 case BC_RGB888:
146                 case BC_YUV888:
147                 case BC_RGBA8888:
148                 case BC_YUVA8888:
149                         CREATE_TABLE(0x100);
150                         break;
152                 case BC_RGB161616:
153                 case BC_YUV161616:
154                 case BC_RGBA16161616:
155                 case BC_YUVA16161616:
156                         CREATE_TABLE(0x10000);
157                         break;
158         }
161 #define PROCESS(table, type, components, yuv) \
162 { \
163         int bytes = w * components; \
164         for(int i = 0; i < h; i++) \
165         { \
166                 type *in_row = (type*)input_ptr->get_rows()[i]; \
167                 type *out_row = (type*)output_ptr->get_rows()[i]; \
169                 if(yuv) \
170                 { \
171 /* Just do Y */ \
172                         for(int j = 0; j < w; j++) \
173                         { \
174                                 out_row[j * components] = table[(int)in_row[j * components]]; \
175                                 out_row[j * components + 1] = in_row[j * components + 1]; \
176                                 out_row[j * components + 2] = in_row[j * components + 2]; \
177                         } \
178                 } \
179                 else \
180                 if(sizeof(type) == 4) \
181                 { \
182                         for(int j = 0; j < w; j++) \
183                         { \
184                                 if(table == forward_table) \
185                                 { \
186                                         out_row[j * components] = (type)(in_row[j * components] * 0.8588 + 0.0627); \
187                                         out_row[j * components + 1] = (type)(in_row[j * components + 1] * 0.8588 + 0.0627); \
188                                         out_row[j * components + 2] = (type)(in_row[j * components + 2] * 0.8588 + 0.0627); \
189                                 } \
190                                 else \
191                                 { \
192                                         out_row[j * components] = (type)(in_row[j * components] * 1.1644 - 0.0627); \
193                                         out_row[j * components + 1] = (type)(in_row[j * components + 1] * 1.1644 - 0.0627); \
194                                         out_row[j * components + 2] = (type)(in_row[j * components + 2] * 1.1644 - 0.0627); \
195                                 } \
196                         } \
197                 } \
198                 else \
199                 { \
200                         for(int j = 0; j < w; j++) \
201                         { \
202                                 out_row[j * components] = table[(int)in_row[j * components]]; \
203                                 out_row[j * components + 1] = table[(int)in_row[j * components + 1]]; \
204                                 out_row[j * components + 2] = table[(int)in_row[j * components + 2]]; \
205                         } \
206                 } \
207         } \
210 void RGB601Main::process(int *table, VFrame *input_ptr, VFrame *output_ptr)
212         int w = input_ptr->get_w();
213         int h = input_ptr->get_h();
214         
215         if(config.direction == 1)
216                 switch(input_ptr->get_color_model())
217                 {
218                         case BC_YUV888:
219                                 PROCESS(forward_table, unsigned char, 3, 1);
220                                 break;
221                         case BC_YUVA8888:
222                                 PROCESS(forward_table, unsigned char, 4, 1);
223                                 break;
224                         case BC_YUV161616:
225                                 PROCESS(forward_table, u_int16_t, 3, 1);
226                                 break;
227                         case BC_YUVA16161616:
228                                 PROCESS(forward_table, u_int16_t, 4, 1);
229                                 break;
230                         case BC_RGB888:
231                                 PROCESS(forward_table, unsigned char, 3, 0);
232                                 break;
233                         case BC_RGBA8888:
234                                 PROCESS(forward_table, unsigned char, 4, 0);
235                                 break;
236                         case BC_RGB_FLOAT:
237                                 PROCESS(forward_table, float, 3, 0);
238                                 break;
239                         case BC_RGBA_FLOAT:
240                                 PROCESS(forward_table, float, 4, 0);
241                                 break;
242                         case BC_RGB161616:
243                                 PROCESS(forward_table, u_int16_t, 3, 0);
244                                 break;
245                         case BC_RGBA16161616:
246                                 PROCESS(forward_table, u_int16_t, 4, 0);
247                                 break;
248                 }
249         else
250         if(config.direction == 2)
251                 switch(input_ptr->get_color_model())
252                 {
253                         case BC_YUV888:
254                                 PROCESS(reverse_table, unsigned char, 3, 1);
255                                 break;
256                         case BC_YUVA8888:
257                                 PROCESS(reverse_table, unsigned char, 4, 1);
258                                 break;
259                         case BC_YUV161616:
260                                 PROCESS(reverse_table, u_int16_t, 3, 1);
261                                 break;
262                         case BC_YUVA16161616:
263                                 PROCESS(reverse_table, u_int16_t, 4, 1);
264                                 break;
265                         case BC_RGB888:
266                                 PROCESS(reverse_table, unsigned char, 3, 0);
267                                 break;
268                         case BC_RGBA8888:
269                                 PROCESS(reverse_table, unsigned char, 4, 0);
270                                 break;
271                         case BC_RGB_FLOAT:
272                                 PROCESS(reverse_table, float, 3, 0);
273                                 break;
274                         case BC_RGBA_FLOAT:
275                                 PROCESS(reverse_table, float, 4, 0);
276                                 break;
277                         case BC_RGB161616:
278                                 PROCESS(reverse_table, u_int16_t, 3, 0);
279                                 break;
280                         case BC_RGBA16161616:
281                                 PROCESS(reverse_table, u_int16_t, 4, 0);
282                                 break;
283                 }
286 int RGB601Main::process_buffer(VFrame *frame,
287         int64_t start_position,
288         double frame_rate)
290         load_configuration();
292         create_table(frame);
294         if(config.direction == 1)
295                 process(forward_table, frame, frame);
296         else
297         if(config.direction == 2)
298                 process(reverse_table, frame, frame);
300         return 0;