]> git.sesse.net Git - vlc/blob - modules/video_filter/atmo/AtmoOutputFilter.cpp
Qt: kill a bunch of warnings
[vlc] / modules / video_filter / atmo / AtmoOutputFilter.cpp
1 /*
2  * AtmoOutputFilter.cpp: Post Processor for the color data retrieved from
3  * a CAtmoInput
4  *
5  * mostly 1:1 from vdr-linux-src "filter.c" copied
6  *
7  * See the README.txt file for copyright information and how to reach the author(s).
8  *
9  * $Id$
10  */
11
12 #ifdef HAVE_CONFIG_H
13 # include "config.h"
14 #endif
15
16 #include <string.h>
17 #include "AtmoOutputFilter.h"
18
19
20
21 CAtmoOutputFilter::CAtmoOutputFilter(CAtmoConfig *atmoConfig )
22 {
23    this->m_pAtmoConfig = atmoConfig;
24    this->m_percent_filter_output_old = NULL;
25    this->m_mean_filter_output_old = NULL;
26    this->m_mean_values = NULL;
27    this->m_mean_sums = NULL;
28    ResetFilter();
29 }
30
31 CAtmoOutputFilter::~CAtmoOutputFilter(void)
32 {
33   if(m_percent_filter_output_old)
34      delete (char *)m_percent_filter_output_old;
35
36   if(m_mean_filter_output_old)
37      delete (char *)m_mean_filter_output_old;
38
39   if(m_mean_values)
40      delete (char *)m_mean_values;
41
42   if(m_mean_sums)
43      delete (char *)m_mean_sums;
44 }
45
46 void CAtmoOutputFilter::ResetFilter(void)
47 {
48   // reset filter values
49   MeanFilter(NULL, true);
50   PercentFilter(NULL, true);
51 }
52
53 pColorPacket CAtmoOutputFilter::Filtering(pColorPacket ColorPacket)
54 {
55   switch (m_pAtmoConfig->getLiveViewFilterMode())
56   {
57     case afmNoFilter:
58          return ColorPacket;
59     break;
60
61     case afmCombined:
62          return MeanFilter(ColorPacket, false);
63     break;
64
65     case afmPercent:
66          return PercentFilter(ColorPacket, false);
67     break;
68   }
69
70   return ColorPacket;
71 }
72
73 pColorPacket CAtmoOutputFilter::PercentFilter(pColorPacket filter_input, ATMO_BOOL init)
74 {
75   // last values needed for the percentage filter
76   if (init) // Initialization
77   {
78     if(m_percent_filter_output_old)
79        delete (char *)m_percent_filter_output_old;
80     m_percent_filter_output_old = NULL;
81     return(NULL);
82   }
83
84   if(!m_percent_filter_output_old || (m_percent_filter_output_old->numColors!=filter_input->numColors)) {
85      delete m_percent_filter_output_old;
86      AllocColorPacket(m_percent_filter_output_old, filter_input->numColors);
87      ZeroColorPacket(m_percent_filter_output_old);
88   }
89
90   int percentNew = this->m_pAtmoConfig->getLiveViewFilter_PercentNew();
91
92   pColorPacket filter_output;
93   AllocColorPacket(filter_output, filter_input->numColors);
94
95   for (int zone = 0; zone < filter_input->numColors; zone++)
96   {
97         filter_output->zone[zone].r = (filter_input->zone[zone].r *
98          (100-percentNew) + m_percent_filter_output_old->zone[zone].r * percentNew) / 100;
99         
100     filter_output->zone[zone].g = (filter_input->zone[zone].g *
101          (100-percentNew) + m_percent_filter_output_old->zone[zone].g * percentNew) / 100;
102
103         filter_output->zone[zone].b = (filter_input->zone[zone].b *
104          (100-percentNew) + m_percent_filter_output_old->zone[zone].b * percentNew) / 100;
105   }
106
107   CopyColorPacket( filter_output, m_percent_filter_output_old );
108
109   delete (char *)filter_input;
110
111   return filter_output;
112 }
113
114 pColorPacket CAtmoOutputFilter::MeanFilter(pColorPacket filter_input, ATMO_BOOL init)
115 {
116   // needed vor the running mean value filter
117
118   // needed for the percentage filter
119   static int filter_length_old;
120   char reinitialize = 0;
121   long int tmp;
122   pColorPacket filter_output;
123
124   if (init) // Initialization
125   {
126     if(m_mean_filter_output_old)
127        delete (char *)m_mean_filter_output_old;
128     m_mean_filter_output_old = NULL;
129
130     if(m_mean_values)
131        delete (char *)m_mean_values;
132     m_mean_values = NULL;
133
134     if(m_mean_sums)
135        delete (char *)m_mean_sums;
136     m_mean_sums = NULL;
137     return (NULL);
138   }
139
140   if(!m_mean_filter_output_old || (m_mean_filter_output_old->numColors!=filter_input->numColors)) {
141         delete m_mean_filter_output_old;
142         AllocColorPacket(m_mean_filter_output_old, filter_input->numColors);
143         ZeroColorPacket(m_mean_filter_output_old);
144   }
145
146   if(!m_mean_values || (m_mean_values->numColors!=filter_input->numColors)) {
147         delete m_mean_values;
148         AllocColorPacket(m_mean_values, filter_input->numColors);
149         ZeroColorPacket(m_mean_values);
150   }
151
152   if(!m_mean_sums || (m_mean_sums->numColors!=filter_input->numColors)) {
153         delete m_mean_sums;
154         AllocLongColorPacket(m_mean_sums, filter_input->numColors);
155         ZeroLongColorPacket(m_mean_sums);
156   }
157
158   AllocColorPacket(filter_output, filter_input->numColors);
159
160
161   int AtmoSetup_Filter_MeanLength = m_pAtmoConfig->getLiveViewFilter_MeanLength();
162   int AtmoSetup_Filter_PercentNew = m_pAtmoConfig->getLiveViewFilter_PercentNew();
163   int AtmoSetup_Filter_MeanThreshold = m_pAtmoConfig->getLiveViewFilter_MeanThreshold();
164
165   // if filter_length has changed
166   if (filter_length_old != AtmoSetup_Filter_MeanLength)
167   {
168     // force reinitialization of the filter
169     reinitialize = 1;
170   }
171   filter_length_old = AtmoSetup_Filter_MeanLength;
172
173   if (filter_length_old < 20) filter_length_old = 20; // avoid division by 0
174
175   for (int zone = 0; zone < filter_input->numColors; zone++)
176   {
177     // calculate the mean-value filters
178       m_mean_sums->longZone[zone].r +=
179         (long int)(filter_input->zone[zone].r - m_mean_values->zone[zone].r); // red
180     tmp = m_mean_sums->longZone[zone].r / ((long int)filter_length_old / 20);
181     if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
182     m_mean_values->zone[zone].r = (unsigned char)tmp;
183
184     m_mean_sums->longZone[zone].g +=
185         (long int)(filter_input->zone[zone].g - m_mean_values->zone[zone].g); // green
186     tmp = m_mean_sums->longZone[zone].g / ((long int)filter_length_old / 20);
187     if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
188     m_mean_values->zone[zone].g = (unsigned char)tmp;
189
190     m_mean_sums->longZone[zone].b +=
191         (long int)(filter_input->zone[zone].b - m_mean_values->zone[zone].b); // blue
192     tmp = m_mean_sums->longZone[zone].b / ((long int)filter_length_old / 20);
193     if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
194     m_mean_values->zone[zone].b = (unsigned char)tmp;
195
196     // check, if there is a jump -> check if differences between actual values and filter values are too big
197
198     long int dist; // distance between the two colors in the 3D RGB space
199     dist = (m_mean_values->zone[zone].r - filter_input->zone[zone].r) *
200            (m_mean_values->zone[zone].r - filter_input->zone[zone].r) +
201            (m_mean_values->zone[zone].g - filter_input->zone[zone].g) *
202            (m_mean_values->zone[zone].g - filter_input->zone[zone].g) +
203            (m_mean_values->zone[zone].b - filter_input->zone[zone].b) *
204            (m_mean_values->zone[zone].b - filter_input->zone[zone].b);
205
206     /*
207        if (dist > 0) { dist = (long int)sqrt((double)dist); }
208        avoid sqrt(0) (TODO: necessary?)
209        I think its cheaper to calculate the square of something ..? insteas geting the square root?
210     */
211     double distMean = ((double)AtmoSetup_Filter_MeanThreshold * 3.6f);
212     distMean = distMean * distMean;
213
214     /*
215       compare calculated distance with the filter threshold
216           if ((dist > (long int)((double)AtmoSetup.Filter_MeanThreshold * 3.6f)) || ( reinitialize == 1))
217    */
218
219         if ((dist > distMean) || ( reinitialize == 1))
220     {
221       // filter jump detected -> set the long filters to the result of the short filters
222       filter_output->zone[zone] = m_mean_values->zone[zone] = filter_input->zone[zone];
223
224       m_mean_sums->longZone[zone].r = filter_input->zone[zone].r *
225                                 (filter_length_old / 20);
226       m_mean_sums->longZone[zone].g = filter_input->zone[zone].g *
227                                 (filter_length_old / 20);
228       m_mean_sums->longZone[zone].b = filter_input->zone[zone].b *
229                                 (filter_length_old / 20);
230     }
231     else
232     {
233       // apply an additional percent filter and return calculated values
234
235           filter_output->zone[zone].r = (m_mean_values->zone[zone].r *
236           (100-AtmoSetup_Filter_PercentNew) +
237           m_mean_filter_output_old->zone[zone].r * AtmoSetup_Filter_PercentNew) / 100;
238
239           filter_output->zone[zone].g = (m_mean_values->zone[zone].g *
240           (100-AtmoSetup_Filter_PercentNew) +
241           m_mean_filter_output_old->zone[zone].g * AtmoSetup_Filter_PercentNew) / 100;
242
243           filter_output->zone[zone].b = (m_mean_values->zone[zone].b *
244           (100-AtmoSetup_Filter_PercentNew) +
245           m_mean_filter_output_old->zone[zone].b * AtmoSetup_Filter_PercentNew) / 100;
246     }
247   }
248
249   CopyColorPacket(filter_output, m_mean_filter_output_old);
250
251   delete (char *)filter_input;
252
253   return(filter_output);
254 }