2 * AtmoOutputFilter.cpp: Post Processor for the color data retrieved from
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).
13 #include "AtmoOutputFilter.h"
17 CAtmoOutputFilter::CAtmoOutputFilter(CAtmoConfig *atmoConfig)
19 this->m_pAtmoConfig = atmoConfig;
23 CAtmoOutputFilter::~CAtmoOutputFilter(void)
27 void CAtmoOutputFilter::ResetFilter(void)
29 // reset filter values
34 tColorPacket CAtmoOutputFilter::Filtering(tColorPacket ColorPacket)
36 filter_input = ColorPacket;
38 switch (m_pAtmoConfig->getLiveViewFilterMode())
41 filter_output = filter_input;
53 filter_output = filter_input;
60 void CAtmoOutputFilter::PercentFilter(ATMO_BOOL init)
62 // last values needed for the percentage filter
63 static tColorPacket filter_output_old;
65 if (init) // Initialization
67 memset(&filter_output_old, 0, sizeof(filter_output_old));
71 int percentNew = this->m_pAtmoConfig->getLiveViewFilter_PercentNew();
73 for (int ch = 0; ch < ATMO_NUM_CHANNELS; ch++)
75 filter_output.channel[ch].r = (filter_input.channel[ch].r *
76 (100-percentNew) + filter_output_old.channel[ch].r * percentNew) / 100;
78 filter_output.channel[ch].g = (filter_input.channel[ch].g *
79 (100-percentNew) + filter_output_old.channel[ch].g * percentNew) / 100;
81 filter_output.channel[ch].b = (filter_input.channel[ch].b *
82 (100-percentNew) + filter_output_old.channel[ch].b * percentNew) / 100;
85 filter_output_old = filter_output;
88 void CAtmoOutputFilter::MeanFilter(ATMO_BOOL init)
90 // needed vor the running mean value filter
91 static tColorPacketLongInt mean_sums;
92 static tColorPacket mean_values;
93 // needed for the percentage filter
94 static tColorPacket filter_output_old;
95 static int filter_length_old;
96 char reinitialize = 0;
99 if (init) // Initialization
101 memset(&filter_output_old, 0, sizeof(filter_output_old));
102 memset(&mean_sums, 0, sizeof(mean_sums));
103 memset(&mean_values, 0, sizeof(mean_values));
106 int AtmoSetup_Filter_MeanLength = m_pAtmoConfig->getLiveViewFilter_MeanLength();
107 int AtmoSetup_Filter_PercentNew = m_pAtmoConfig->getLiveViewFilter_PercentNew();
108 int AtmoSetup_Filter_MeanThreshold = m_pAtmoConfig->getLiveViewFilter_MeanThreshold();
110 // if filter_length has changed
111 if (filter_length_old != AtmoSetup_Filter_MeanLength)
113 // force reinitialization of the filter
116 filter_length_old = AtmoSetup_Filter_MeanLength;
118 if (filter_length_old < 20) filter_length_old = 20; // avoid division by 0
120 for (int ch = 0; ch < ATMO_NUM_CHANNELS; ch++)
122 // calculate the mean-value filters
123 mean_sums.channel[ch].r +=
124 (long int)(filter_input.channel[ch].r - mean_values.channel[ch].r); // red
125 tmp = mean_sums.channel[ch].r / ((long int)filter_length_old / 20);
126 if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
127 mean_values.channel[ch].r = (unsigned char)tmp;
129 mean_sums.channel[ch].g +=
130 (long int)(filter_input.channel[ch].g - mean_values.channel[ch].g); // green
131 tmp = mean_sums.channel[ch].g / ((long int)filter_length_old / 20);
132 if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
133 mean_values.channel[ch].g = (unsigned char)tmp;
135 mean_sums.channel[ch].b +=
136 (long int)(filter_input.channel[ch].b - mean_values.channel[ch].b); // blue
137 tmp = mean_sums.channel[ch].b / ((long int)filter_length_old / 20);
138 if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
139 mean_values.channel[ch].b = (unsigned char)tmp;
141 // check, if there is a jump -> check if differences between actual values and filter values are too big
143 long int dist; // distance between the two colors in the 3D RGB space
144 dist = (mean_values.channel[ch].r - filter_input.channel[ch].r) *
145 (mean_values.channel[ch].r - filter_input.channel[ch].r) +
146 (mean_values.channel[ch].g - filter_input.channel[ch].g) *
147 (mean_values.channel[ch].g - filter_input.channel[ch].g) +
148 (mean_values.channel[ch].b - filter_input.channel[ch].b) *
149 (mean_values.channel[ch].b - filter_input.channel[ch].b);
152 if (dist > 0) { dist = (long int)sqrt((double)dist); }
153 avoid sqrt(0) (TODO: necessary?)
154 I think its cheaper to calculate the square of something ..? insteas geting the square root?
156 double distMean = ((double)AtmoSetup_Filter_MeanThreshold * 3.6f);
157 distMean = distMean * distMean;
160 compare calculated distance with the filter threshold
161 if ((dist > (long int)((double)AtmoSetup.Filter_MeanThreshold * 3.6f)) || ( reinitialize == 1))
164 if ((dist > distMean) || ( reinitialize == 1))
166 // filter jump detected -> set the long filters to the result of the short filters
167 filter_output.channel[ch] = mean_values.channel[ch] = filter_input.channel[ch];
169 mean_sums.channel[ch].r = filter_input.channel[ch].r *
170 (filter_length_old / 20);
171 mean_sums.channel[ch].g = filter_input.channel[ch].g *
172 (filter_length_old / 20);
173 mean_sums.channel[ch].b = filter_input.channel[ch].b *
174 (filter_length_old / 20);
178 // apply an additional percent filter and return calculated values
180 filter_output.channel[ch].r = (mean_values.channel[ch].r *
181 (100-AtmoSetup_Filter_PercentNew) +
182 filter_output_old.channel[ch].r * AtmoSetup_Filter_PercentNew) / 100;
184 filter_output.channel[ch].g = (mean_values.channel[ch].g *
185 (100-AtmoSetup_Filter_PercentNew) +
186 filter_output_old.channel[ch].g * AtmoSetup_Filter_PercentNew) / 100;
188 filter_output.channel[ch].b = (mean_values.channel[ch].b *
189 (100-AtmoSetup_Filter_PercentNew) +
190 filter_output_old.channel[ch].b * AtmoSetup_Filter_PercentNew) / 100;
193 filter_output_old = filter_output;