add_integer: remove callback parameter
[vlc/asuraparaju-public.git] / modules / video_filter / atmo / AtmoOutputFilter.cpp
blob8d8030c01820cedc9e4724a17ac36b23b384d60b
1 /*
2 * AtmoOutputFilter.cpp: Post Processor for the color data retrieved from
3 * a CAtmoInput
5 * mostly 1:1 from vdr-linux-src "filter.c" copied
7 * See the README.txt file for copyright information and how to reach the author(s).
9 * $Id$
12 #include <string.h>
13 #include "AtmoOutputFilter.h"
17 CAtmoOutputFilter::CAtmoOutputFilter(CAtmoConfig *atmoConfig )
19 this->m_pAtmoConfig = atmoConfig;
20 this->m_percent_filter_output_old = NULL;
21 this->m_mean_filter_output_old = NULL;
22 this->m_mean_values = NULL;
23 this->m_mean_sums = NULL;
24 ResetFilter();
27 CAtmoOutputFilter::~CAtmoOutputFilter(void)
29 if(m_percent_filter_output_old)
30 delete (char *)m_percent_filter_output_old;
32 if(m_mean_filter_output_old)
33 delete (char *)m_mean_filter_output_old;
35 if(m_mean_values)
36 delete (char *)m_mean_values;
38 if(m_mean_sums)
39 delete (char *)m_mean_sums;
42 void CAtmoOutputFilter::ResetFilter(void)
44 // reset filter values
45 MeanFilter(NULL, true);
46 PercentFilter(NULL, true);
49 pColorPacket CAtmoOutputFilter::Filtering(pColorPacket ColorPacket)
51 switch (m_pAtmoConfig->getLiveViewFilterMode())
53 case afmNoFilter:
54 return ColorPacket;
55 break;
57 case afmCombined:
58 return MeanFilter(ColorPacket, false);
59 break;
61 case afmPercent:
62 return PercentFilter(ColorPacket, false);
63 break;
66 return ColorPacket;
69 pColorPacket CAtmoOutputFilter::PercentFilter(pColorPacket filter_input, ATMO_BOOL init)
71 // last values needed for the percentage filter
72 if (init) // Initialization
74 if(m_percent_filter_output_old)
75 delete (char *)m_percent_filter_output_old;
76 m_percent_filter_output_old = NULL;
77 return(NULL);
80 if(!m_percent_filter_output_old || (m_percent_filter_output_old->numColors!=filter_input->numColors)) {
81 delete m_percent_filter_output_old;
82 AllocColorPacket(m_percent_filter_output_old, filter_input->numColors);
83 ZeroColorPacket(m_percent_filter_output_old);
86 int percentNew = this->m_pAtmoConfig->getLiveViewFilter_PercentNew();
88 pColorPacket filter_output;
89 AllocColorPacket(filter_output, filter_input->numColors);
91 for (int zone = 0; zone < filter_input->numColors; zone++)
93 filter_output->zone[zone].r = (filter_input->zone[zone].r *
94 (100-percentNew) + m_percent_filter_output_old->zone[zone].r * percentNew) / 100;
96 filter_output->zone[zone].g = (filter_input->zone[zone].g *
97 (100-percentNew) + m_percent_filter_output_old->zone[zone].g * percentNew) / 100;
99 filter_output->zone[zone].b = (filter_input->zone[zone].b *
100 (100-percentNew) + m_percent_filter_output_old->zone[zone].b * percentNew) / 100;
103 CopyColorPacket( filter_output, m_percent_filter_output_old );
105 delete (char *)filter_input;
107 return filter_output;
110 pColorPacket CAtmoOutputFilter::MeanFilter(pColorPacket filter_input, ATMO_BOOL init)
112 // needed vor the running mean value filter
114 // needed for the percentage filter
115 static int filter_length_old;
116 char reinitialize = 0;
117 long int tmp;
118 pColorPacket filter_output;
120 if (init) // Initialization
122 if(m_mean_filter_output_old)
123 delete (char *)m_mean_filter_output_old;
124 m_mean_filter_output_old = NULL;
126 if(m_mean_values)
127 delete (char *)m_mean_values;
128 m_mean_values = NULL;
130 if(m_mean_sums)
131 delete (char *)m_mean_sums;
132 m_mean_sums = NULL;
133 return (NULL);
136 if(!m_mean_filter_output_old || (m_mean_filter_output_old->numColors!=filter_input->numColors)) {
137 delete m_mean_filter_output_old;
138 AllocColorPacket(m_mean_filter_output_old, filter_input->numColors);
139 ZeroColorPacket(m_mean_filter_output_old);
142 if(!m_mean_values || (m_mean_values->numColors!=filter_input->numColors)) {
143 delete m_mean_values;
144 AllocColorPacket(m_mean_values, filter_input->numColors);
145 ZeroColorPacket(m_mean_values);
148 if(!m_mean_sums || (m_mean_sums->numColors!=filter_input->numColors)) {
149 delete m_mean_sums;
150 AllocLongColorPacket(m_mean_sums, filter_input->numColors);
151 ZeroLongColorPacket(m_mean_sums);
154 AllocColorPacket(filter_output, filter_input->numColors);
157 int AtmoSetup_Filter_MeanLength = m_pAtmoConfig->getLiveViewFilter_MeanLength();
158 int AtmoSetup_Filter_PercentNew = m_pAtmoConfig->getLiveViewFilter_PercentNew();
159 int AtmoSetup_Filter_MeanThreshold = m_pAtmoConfig->getLiveViewFilter_MeanThreshold();
161 // if filter_length has changed
162 if (filter_length_old != AtmoSetup_Filter_MeanLength)
164 // force reinitialization of the filter
165 reinitialize = 1;
167 filter_length_old = AtmoSetup_Filter_MeanLength;
169 if (filter_length_old < 20) filter_length_old = 20; // avoid division by 0
171 for (int zone = 0; zone < filter_input->numColors; zone++)
173 // calculate the mean-value filters
174 m_mean_sums->longZone[zone].r +=
175 (long int)(filter_input->zone[zone].r - m_mean_values->zone[zone].r); // red
176 tmp = m_mean_sums->longZone[zone].r / ((long int)filter_length_old / 20);
177 if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
178 m_mean_values->zone[zone].r = (unsigned char)tmp;
180 m_mean_sums->longZone[zone].g +=
181 (long int)(filter_input->zone[zone].g - m_mean_values->zone[zone].g); // green
182 tmp = m_mean_sums->longZone[zone].g / ((long int)filter_length_old / 20);
183 if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
184 m_mean_values->zone[zone].g = (unsigned char)tmp;
186 m_mean_sums->longZone[zone].b +=
187 (long int)(filter_input->zone[zone].b - m_mean_values->zone[zone].b); // blue
188 tmp = m_mean_sums->longZone[zone].b / ((long int)filter_length_old / 20);
189 if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
190 m_mean_values->zone[zone].b = (unsigned char)tmp;
192 // check, if there is a jump -> check if differences between actual values and filter values are too big
194 long int dist; // distance between the two colors in the 3D RGB space
195 dist = (m_mean_values->zone[zone].r - filter_input->zone[zone].r) *
196 (m_mean_values->zone[zone].r - filter_input->zone[zone].r) +
197 (m_mean_values->zone[zone].g - filter_input->zone[zone].g) *
198 (m_mean_values->zone[zone].g - filter_input->zone[zone].g) +
199 (m_mean_values->zone[zone].b - filter_input->zone[zone].b) *
200 (m_mean_values->zone[zone].b - filter_input->zone[zone].b);
203 if (dist > 0) { dist = (long int)sqrt((double)dist); }
204 avoid sqrt(0) (TODO: necessary?)
205 I think its cheaper to calculate the square of something ..? insteas geting the square root?
207 double distMean = ((double)AtmoSetup_Filter_MeanThreshold * 3.6f);
208 distMean = distMean * distMean;
211 compare calculated distance with the filter threshold
212 if ((dist > (long int)((double)AtmoSetup.Filter_MeanThreshold * 3.6f)) || ( reinitialize == 1))
215 if ((dist > distMean) || ( reinitialize == 1))
217 // filter jump detected -> set the long filters to the result of the short filters
218 filter_output->zone[zone] = m_mean_values->zone[zone] = filter_input->zone[zone];
220 m_mean_sums->longZone[zone].r = filter_input->zone[zone].r *
221 (filter_length_old / 20);
222 m_mean_sums->longZone[zone].g = filter_input->zone[zone].g *
223 (filter_length_old / 20);
224 m_mean_sums->longZone[zone].b = filter_input->zone[zone].b *
225 (filter_length_old / 20);
227 else
229 // apply an additional percent filter and return calculated values
231 filter_output->zone[zone].r = (m_mean_values->zone[zone].r *
232 (100-AtmoSetup_Filter_PercentNew) +
233 m_mean_filter_output_old->zone[zone].r * AtmoSetup_Filter_PercentNew) / 100;
235 filter_output->zone[zone].g = (m_mean_values->zone[zone].g *
236 (100-AtmoSetup_Filter_PercentNew) +
237 m_mean_filter_output_old->zone[zone].g * AtmoSetup_Filter_PercentNew) / 100;
239 filter_output->zone[zone].b = (m_mean_values->zone[zone].b *
240 (100-AtmoSetup_Filter_PercentNew) +
241 m_mean_filter_output_old->zone[zone].b * AtmoSetup_Filter_PercentNew) / 100;
245 CopyColorPacket(filter_output, m_mean_filter_output_old);
247 delete (char *)filter_input;
249 return(filter_output);