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 "bistogramconfig.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 return !current_this ^ !current_src ? 0 : 1;
125 void HistogramPoints::copy_from(HistogramPoints *src)
129 HistogramPoint *current = src->first;
132 HistogramPoint *new_point = new HistogramPoint;
133 new_point->x = current->x;
134 new_point->y = current->y;
140 void HistogramPoints::interpolate(HistogramPoints *prev,
141 HistogramPoints *next,
145 HistogramPoint *current = first;
146 HistogramPoint *current_prev = prev->first;
147 HistogramPoint *current_next = next->first;
149 while(current && current_prev && current_next)
151 current->x = current_prev->x * prev_scale +
152 current_next->x * next_scale;
153 current->y = current_prev->y * prev_scale +
154 current_next->y * next_scale;
156 current_prev = current_prev->next;
157 current_next = current_next->next;
174 HistogramConfig::HistogramConfig()
179 void HistogramConfig::reset(int do_mode)
184 for(int i = 0; i < HISTOGRAM_MODES; i++)
199 void HistogramConfig::reset_points()
201 for(int i = 0; i < HISTOGRAM_MODES; i++)
203 while(points[i].last) delete points[i].last;
204 points[i].insert(0.0,0.0);
205 points[i].last->gradient = 1.0;
206 points[i].insert(1.0,1.0);
207 points[i].last->gradient = 1.0;
212 void HistogramConfig::boundaries()
214 for(int i = 0; i < HISTOGRAM_MODES; i++)
216 points[i].boundaries();
217 CLAMP(output_min[i], HIST_MIN_INPUT, HIST_MAX_INPUT);
218 CLAMP(output_max[i], HIST_MIN_INPUT, HIST_MAX_INPUT);
219 output_min[i] = Units::quantize(output_min[i], PRECISION);
220 output_max[i] = Units::quantize(output_max[i], PRECISION);
222 CLAMP(threshold, 0, 1);
225 int HistogramConfig::equivalent(HistogramConfig &that)
227 for(int i = 0; i < HISTOGRAM_MODES; i++)
229 if(!points[i].equivalent(&that.points[i]) ||
230 !EQUIV(output_min[i], that.output_min[i]) ||
231 !EQUIV(output_max[i], that.output_max[i])) return 0;
234 if(automatic != that.automatic ||
235 !EQUIV(threshold, that.threshold)) return 0;
240 void HistogramConfig::copy_from(HistogramConfig &that)
242 for(int i = 0; i < HISTOGRAM_MODES; i++)
244 points[i].copy_from(&that.points[i]);
245 output_min[i] = that.output_min[i];
246 output_max[i] = that.output_max[i];
249 automatic = that.automatic;
250 threshold = that.threshold;
252 smoothMode = that.smoothMode;
255 void HistogramConfig::interpolate(HistogramConfig &prev,
256 HistogramConfig &next,
259 int64_t current_frame)
261 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
262 double prev_scale = 1.0 - next_scale;
264 for(int i = 0; i < HISTOGRAM_MODES; i++)
266 points[i].interpolate(&prev.points[i], &next.points[i], next_scale, prev_scale);
267 output_min[i] = prev.output_min[i] * prev_scale + next.output_min[i] * next_scale;
268 output_max[i] = prev.output_max[i] * prev_scale + next.output_max[i] * next_scale;
271 threshold = prev.threshold * prev_scale + next.threshold * next_scale;
272 automatic = prev.automatic;
274 smoothMode = prev.smoothMode;
278 void HistogramConfig::dump()
280 for(int j = 0; j < HISTOGRAM_MODES; j++)
282 printf("HistogramConfig::dump mode=%d\n", j);
283 HistogramPoints *points = &this->points[j];
284 HistogramPoint *current = points->first;
287 printf("%f,%f ", current->x, current->y);