update internationalization data
[goodguy/history.git] / cinelerra-5.0 / plugins / histogram_bezier / histogramconfig.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 "clip.h"
23 #include "histogramconfig.h"
24 #include "units.h"
25
26 #include <math.h>
27
28
29
30
31 HistogramPoint::HistogramPoint()
32  : ListItem<HistogramPoint>()
33 {
34 }
35
36 HistogramPoint::~HistogramPoint()
37 {
38 }
39
40 int HistogramPoint::equivalent(HistogramPoint *src)
41 {
42         return EQUIV(x, src->x) && EQUIV(y, src->y) && EQUIV(gradient, src->gradient);
43 }
44
45
46
47
48 HistogramPoints::HistogramPoints()
49  : List<HistogramPoint>()
50 {
51         insert(0.0,0.0);
52         first->gradient = 1.0;
53         first->xoffset_left = 0.0;
54         first->xoffset_right = 0.05;
55         insert(1.0,1.0);
56         last->gradient = 1.0;  
57         last->xoffset_left = -0.05;
58         last->xoffset_right = 0.0;
59         
60 }
61
62 HistogramPoints::~HistogramPoints()
63 {
64 }
65
66 HistogramPoint* HistogramPoints::insert(float x, float y)
67 {
68         HistogramPoint *current = first;
69
70 // Get existing point after new point
71         while(current)
72         {
73                 if(current->x > x)
74                         break;
75                 else
76                         current = NEXT;
77         }
78
79 // Insert new point before current point
80         HistogramPoint *new_point = new HistogramPoint;
81         if(current)
82         {
83                 insert_before(current, new_point);
84         }
85         else
86 // Append new point to list
87         {
88                 append(new_point);
89         }
90
91         new_point->x = x;
92         new_point->y = y;
93         new_point->xoffset_left = -0.05;
94         new_point->xoffset_right = 0.05;
95
96
97         return new_point;
98 }
99
100 void HistogramPoints::boundaries()
101 {
102         HistogramPoint *current = first;
103         while(current)
104         {
105                 CLAMP(current->x, 0.0, 1.0);
106                 CLAMP(current->y, 0.0, 1.0);
107                 current = NEXT;
108         }
109 }
110
111 int HistogramPoints::equivalent(HistogramPoints *src)
112 {
113         HistogramPoint *current_this = first;
114         HistogramPoint *current_src = src->first;
115         while(current_this && current_src)
116         {
117                 if(!current_this->equivalent(current_src)) return 0;
118                 current_this = current_this->next;
119                 current_src = current_src->next;
120         }
121
122         if(!current_this && current_src ||
123                 current_this && !current_src)
124                 return 0;
125         return 1;
126 }
127
128 void HistogramPoints::copy_from(HistogramPoints *src)
129 {
130         while(last)
131                 delete last;
132         HistogramPoint *current = src->first;
133         while(current)
134         {
135                 HistogramPoint *new_point = new HistogramPoint;
136                 new_point->x = current->x;
137                 new_point->y = current->y;
138                 append(new_point);
139                 current = NEXT;
140         }
141 }
142
143 void HistogramPoints::interpolate(HistogramPoints *prev, 
144         HistogramPoints *next,
145         double prev_scale,
146         double next_scale)
147 {
148         HistogramPoint *current = first;
149         HistogramPoint *current_prev = prev->first;
150         HistogramPoint *current_next = next->first;
151
152         while(current && current_prev && current_next)
153         {
154                 current->x = current_prev->x * prev_scale +
155                         current_next->x * next_scale;
156                 current->y = current_prev->y * prev_scale +
157                         current_next->y * next_scale;
158                 current = NEXT;
159                 current_prev = current_prev->next;
160                 current_next = current_next->next;
161         }
162 }
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177 HistogramConfig::HistogramConfig()
178 {
179         reset(1);
180 }
181
182 void HistogramConfig::reset(int do_mode)
183 {
184         reset_points();
185
186         
187         for(int i = 0; i < HISTOGRAM_MODES; i++)
188         {
189                 output_min[i] = 0.0;
190                 output_max[i] = 1.0;
191         }
192
193         if(do_mode) 
194         {
195                 automatic = 0;
196                 threshold = 0.1;
197                 split = 0;
198                 smoothMode = 0;
199         }
200 }
201
202 void HistogramConfig::reset_points()
203 {
204         for(int i = 0; i < HISTOGRAM_MODES; i++)
205         {
206                 while(points[i].last) delete points[i].last;
207                 points[i].insert(0.0,0.0);
208                 points[i].last->gradient = 1.0;
209                 points[i].insert(1.0,1.0);
210                 points[i].last->gradient = 1.0;
211         }
212 }
213
214
215 void HistogramConfig::boundaries()
216 {
217         for(int i = 0; i < HISTOGRAM_MODES; i++)
218         {
219                 points[i].boundaries();
220                 CLAMP(output_min[i], HIST_MIN_INPUT, HIST_MAX_INPUT);
221                 CLAMP(output_max[i], HIST_MIN_INPUT, HIST_MAX_INPUT);
222                 output_min[i] = Units::quantize(output_min[i], PRECISION);
223                 output_max[i] = Units::quantize(output_max[i], PRECISION);
224         }
225         CLAMP(threshold, 0, 1);
226 }
227
228 int HistogramConfig::equivalent(HistogramConfig &that)
229 {
230         for(int i = 0; i < HISTOGRAM_MODES; i++)
231         {
232                 if(!points[i].equivalent(&that.points[i]) ||
233                         !EQUIV(output_min[i], that.output_min[i]) ||
234                         !EQUIV(output_max[i], that.output_max[i])) return 0;
235         }
236
237         if(automatic != that.automatic ||
238                 !EQUIV(threshold, that.threshold)) return 0;
239
240         return 1;
241 }
242
243 void HistogramConfig::copy_from(HistogramConfig &that)
244 {
245         for(int i = 0; i < HISTOGRAM_MODES; i++)
246         {
247                 points[i].copy_from(&that.points[i]);
248                 output_min[i] = that.output_min[i];
249                 output_max[i] = that.output_max[i];
250         }
251
252         automatic = that.automatic;
253         threshold = that.threshold;
254         split = that.split;
255         smoothMode = that.smoothMode;
256 }
257
258 void HistogramConfig::interpolate(HistogramConfig &prev, 
259         HistogramConfig &next, 
260         int64_t prev_frame, 
261         int64_t next_frame, 
262         int64_t current_frame)
263 {
264         double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
265         double prev_scale = 1.0 - next_scale;
266
267         for(int i = 0; i < HISTOGRAM_MODES; i++)
268         {
269                 points[i].interpolate(&prev.points[i], &next.points[i], next_scale, prev_scale);
270                 output_min[i] = prev.output_min[i] * prev_scale + next.output_min[i] * next_scale;
271                 output_max[i] = prev.output_max[i] * prev_scale + next.output_max[i] * next_scale;
272         }
273
274         threshold = prev.threshold * prev_scale + next.threshold * next_scale;
275         automatic = prev.automatic;
276         split = prev.split;
277         smoothMode = prev.smoothMode;
278 }
279
280
281 void HistogramConfig::dump()
282 {
283         for(int j = 0; j < HISTOGRAM_MODES; j++)
284         {
285                 printf("HistogramConfig::dump mode=%d\n", j);
286                 HistogramPoints *points = &this->points[j];
287                 HistogramPoint *current = points->first;
288                 while(current)
289                 {
290                         printf("%f,%f ", current->x, current->y);
291                         fflush(stdout);
292                         current = NEXT;
293                 }
294                 printf("\n");
295         }
296 }
297
298
299