4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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.
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.
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
23 #include "histogramconfig.h"
31 HistogramPoint::HistogramPoint()
32 : ListItem<HistogramPoint>()
36 HistogramPoint::~HistogramPoint()
40 int HistogramPoint::equivalent(HistogramPoint *src)
42 return EQUIV(x, src->x) && EQUIV(y, src->y) && EQUIV(gradient, src->gradient);
48 HistogramPoints::HistogramPoints()
49 : List<HistogramPoint>()
52 first->gradient = 1.0;
53 first->xoffset_left = 0.0;
54 first->xoffset_right = 0.05;
57 last->xoffset_left = -0.05;
58 last->xoffset_right = 0.0;
62 HistogramPoints::~HistogramPoints()
66 HistogramPoint* HistogramPoints::insert(float x, float y)
68 HistogramPoint *current = first;
70 // Get existing point after new point
79 // Insert new point before current point
80 HistogramPoint *new_point = new HistogramPoint;
83 insert_before(current, new_point);
86 // Append new point to list
93 new_point->xoffset_left = -0.05;
94 new_point->xoffset_right = 0.05;
100 void HistogramPoints::boundaries()
102 HistogramPoint *current = first;
105 CLAMP(current->x, 0.0, 1.0);
106 CLAMP(current->y, 0.0, 1.0);
111 int HistogramPoints::equivalent(HistogramPoints *src)
113 HistogramPoint *current_this = first;
114 HistogramPoint *current_src = src->first;
115 while(current_this && current_src)
117 if(!current_this->equivalent(current_src)) return 0;
118 current_this = current_this->next;
119 current_src = current_src->next;
122 if(!current_this && current_src ||
123 current_this && !current_src)
128 void HistogramPoints::copy_from(HistogramPoints *src)
132 HistogramPoint *current = src->first;
135 HistogramPoint *new_point = new HistogramPoint;
136 new_point->x = current->x;
137 new_point->y = current->y;
143 void HistogramPoints::interpolate(HistogramPoints *prev,
144 HistogramPoints *next,
148 HistogramPoint *current = first;
149 HistogramPoint *current_prev = prev->first;
150 HistogramPoint *current_next = next->first;
152 while(current && current_prev && current_next)
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;
159 current_prev = current_prev->next;
160 current_next = current_next->next;
177 HistogramConfig::HistogramConfig()
182 void HistogramConfig::reset(int do_mode)
187 for(int i = 0; i < HISTOGRAM_MODES; i++)
202 void HistogramConfig::reset_points()
204 for(int i = 0; i < HISTOGRAM_MODES; i++)
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;
215 void HistogramConfig::boundaries()
217 for(int i = 0; i < HISTOGRAM_MODES; i++)
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);
225 CLAMP(threshold, 0, 1);
228 int HistogramConfig::equivalent(HistogramConfig &that)
230 for(int i = 0; i < HISTOGRAM_MODES; i++)
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;
237 if(automatic != that.automatic ||
238 !EQUIV(threshold, that.threshold)) return 0;
243 void HistogramConfig::copy_from(HistogramConfig &that)
245 for(int i = 0; i < HISTOGRAM_MODES; i++)
247 points[i].copy_from(&that.points[i]);
248 output_min[i] = that.output_min[i];
249 output_max[i] = that.output_max[i];
252 automatic = that.automatic;
253 threshold = that.threshold;
255 smoothMode = that.smoothMode;
258 void HistogramConfig::interpolate(HistogramConfig &prev,
259 HistogramConfig &next,
262 int64_t current_frame)
264 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
265 double prev_scale = 1.0 - next_scale;
267 for(int i = 0; i < HISTOGRAM_MODES; i++)
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;
274 threshold = prev.threshold * prev_scale + next.threshold * next_scale;
275 automatic = prev.automatic;
277 smoothMode = prev.smoothMode;
281 void HistogramConfig::dump()
283 for(int j = 0; j < HISTOGRAM_MODES; j++)
285 printf("HistogramConfig::dump mode=%d\n", j);
286 HistogramPoints *points = &this->points[j];
287 HistogramPoint *current = points->first;
290 printf("%f,%f ", current->x, current->y);