00001 #include "clip.h"
00002 #include "histogramconfig.h"
00003 #include "units.h"
00004
00005 #include <math.h>
00006
00007
00008
00009
00010
00011 HistogramPoint::HistogramPoint()
00012 : ListItem<HistogramPoint>()
00013 {
00014 }
00015
00016 HistogramPoint::~HistogramPoint()
00017 {
00018 }
00019
00020 int HistogramPoint::equivalent(HistogramPoint *src)
00021 {
00022 return EQUIV(x, src->x) && EQUIV(y, src->y);
00023 }
00024
00025
00026
00027
00028 HistogramPoints::HistogramPoints()
00029 : List<HistogramPoint>()
00030 {
00031 }
00032
00033 HistogramPoints::~HistogramPoints()
00034 {
00035 }
00036
00037 HistogramPoint* HistogramPoints::insert(float x, float y)
00038 {
00039 HistogramPoint *current = first;
00040
00041
00042 while(current)
00043 {
00044 if(current->x > x)
00045 break;
00046 else
00047 current = NEXT;
00048 }
00049
00050
00051 HistogramPoint *new_point = new HistogramPoint;
00052 if(current)
00053 {
00054 insert_before(current, new_point);
00055 }
00056 else
00057
00058 {
00059 append(new_point);
00060 }
00061
00062 new_point->x = x;
00063 new_point->y = y;
00064
00065
00066 return new_point;
00067 }
00068
00069 void HistogramPoints::boundaries()
00070 {
00071 HistogramPoint *current = first;
00072 while(current)
00073 {
00074 CLAMP(current->x, 0.0, 1.0);
00075 CLAMP(current->y, 0.0, 1.0);
00076 current = NEXT;
00077 }
00078 }
00079
00080 int HistogramPoints::equivalent(HistogramPoints *src)
00081 {
00082 HistogramPoint *current_this = first;
00083 HistogramPoint *current_src = src->first;
00084 while(current_this && current_src)
00085 {
00086 if(!current_this->equivalent(current_src)) return 0;
00087 current_this = current_this->next;
00088 current_src = current_src->next;
00089 }
00090
00091 if(!current_this && current_src ||
00092 current_this && !current_src)
00093 return 0;
00094 return 1;
00095 }
00096
00097 void HistogramPoints::copy_from(HistogramPoints *src)
00098 {
00099 while(last)
00100 delete last;
00101 HistogramPoint *current = src->first;
00102 while(current)
00103 {
00104 HistogramPoint *new_point = new HistogramPoint;
00105 new_point->x = current->x;
00106 new_point->y = current->y;
00107 append(new_point);
00108 current = NEXT;
00109 }
00110 }
00111
00112 void HistogramPoints::interpolate(HistogramPoints *prev,
00113 HistogramPoints *next,
00114 double prev_scale,
00115 double next_scale)
00116 {
00117 HistogramPoint *current = first;
00118 HistogramPoint *current_prev = prev->first;
00119 HistogramPoint *current_next = next->first;
00120
00121 while(current && current_prev && current_next)
00122 {
00123 current->x = current_prev->x * prev_scale +
00124 current_next->x * next_scale;
00125 current->y = current_prev->y * prev_scale +
00126 current_next->y * next_scale;
00127 current = NEXT;
00128 current_prev = current_prev->next;
00129 current_next = current_next->next;
00130 }
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 HistogramConfig::HistogramConfig()
00147 {
00148 plot = 1;
00149 split = 0;
00150 reset(1);
00151 }
00152
00153 void HistogramConfig::reset(int do_mode)
00154 {
00155 reset_points(0);
00156
00157
00158 for(int i = 0; i < HISTOGRAM_MODES; i++)
00159 {
00160 output_min[i] = 0.0;
00161 output_max[i] = 1.0;
00162 }
00163
00164 if(do_mode)
00165 {
00166 automatic = 0;
00167 threshold = 0.1;
00168 }
00169 }
00170
00171 void HistogramConfig::reset_points(int colors_only)
00172 {
00173 for(int i = 0; i < HISTOGRAM_MODES; i++)
00174 {
00175 if(i != HISTOGRAM_VALUE || !colors_only)
00176 while(points[i].last) delete points[i].last;
00177 }
00178 }
00179
00180
00181 void HistogramConfig::boundaries()
00182 {
00183 for(int i = 0; i < HISTOGRAM_MODES; i++)
00184 {
00185 points[i].boundaries();
00186 CLAMP(output_min[i], MIN_INPUT, MAX_INPUT);
00187 CLAMP(output_max[i], MIN_INPUT, MAX_INPUT);
00188 output_min[i] = Units::quantize(output_min[i], PRECISION);
00189 output_max[i] = Units::quantize(output_max[i], PRECISION);
00190 }
00191 CLAMP(threshold, 0, 1);
00192 }
00193
00194 int HistogramConfig::equivalent(HistogramConfig &that)
00195 {
00196 for(int i = 0; i < HISTOGRAM_MODES; i++)
00197 {
00198 if(!points[i].equivalent(&that.points[i]) ||
00199 !EQUIV(output_min[i], that.output_min[i]) ||
00200 !EQUIV(output_max[i], that.output_max[i])) return 0;
00201 }
00202
00203 if(automatic != that.automatic ||
00204 !EQUIV(threshold, that.threshold)) return 0;
00205
00206 if(plot != that.plot ||
00207 split != that.split) return 0;
00208 return 1;
00209 }
00210
00211 void HistogramConfig::copy_from(HistogramConfig &that)
00212 {
00213 for(int i = 0; i < HISTOGRAM_MODES; i++)
00214 {
00215 points[i].copy_from(&that.points[i]);
00216 output_min[i] = that.output_min[i];
00217 output_max[i] = that.output_max[i];
00218 }
00219
00220 automatic = that.automatic;
00221 threshold = that.threshold;
00222 plot = that.plot;
00223 split = that.split;
00224 }
00225
00226 void HistogramConfig::interpolate(HistogramConfig &prev,
00227 HistogramConfig &next,
00228 int64_t prev_frame,
00229 int64_t next_frame,
00230 int64_t current_frame)
00231 {
00232 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
00233 double prev_scale = 1.0 - next_scale;
00234
00235 for(int i = 0; i < HISTOGRAM_MODES; i++)
00236 {
00237 points[i].interpolate(&prev.points[i], &next.points[i], prev_scale, next_scale);
00238 output_min[i] = prev.output_min[i] * prev_scale + next.output_min[i] * next_scale;
00239 output_max[i] = prev.output_max[i] * prev_scale + next.output_max[i] * next_scale;
00240 }
00241
00242 threshold = prev.threshold * prev_scale + next.threshold * next_scale;
00243 automatic = prev.automatic;
00244 plot = prev.plot;
00245 split = prev.split;
00246 }
00247
00248
00249 void HistogramConfig::dump()
00250 {
00251 for(int j = 0; j < HISTOGRAM_MODES; j++)
00252 {
00253 printf("HistogramConfig::dump mode=%d plot=%d split=%d\n", j, plot, split);
00254 HistogramPoints *points = &this->points[j];
00255 HistogramPoint *current = points->first;
00256 while(current)
00257 {
00258 printf("%f,%f ", current->x, current->y);
00259 fflush(stdout);
00260 current = NEXT;
00261 }
00262 printf("\n");
00263 }
00264 }
00265
00266
00267