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
;
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
;
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
;
36 delete (char *)m_mean_values
;
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())
58 return MeanFilter(ColorPacket
, false);
62 return PercentFilter(ColorPacket
, false);
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
;
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;
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
;
127 delete (char *)m_mean_values
;
128 m_mean_values
= NULL
;
131 delete (char *)m_mean_sums
;
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
)) {
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
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);
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
);