AtmoOutputFilter.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:6k
源码类别:

midi

开发平台:

Unix_Linux

  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: 3cefa0033c5aee8bf19329c1fc064368c7f50c6c $
  10.  */
  11. #include <string.h>
  12. #include "AtmoOutputFilter.h"
  13. CAtmoOutputFilter::CAtmoOutputFilter(CAtmoConfig *atmoConfig)
  14. {
  15.    this->m_pAtmoConfig = atmoConfig;
  16.    ResetFilter();
  17. }
  18. CAtmoOutputFilter::~CAtmoOutputFilter(void)
  19. {
  20. }
  21. void CAtmoOutputFilter::ResetFilter(void)
  22. {
  23.   // reset filter values
  24.   MeanFilter(true);
  25.   PercentFilter(true);
  26. }
  27. tColorPacket CAtmoOutputFilter::Filtering(tColorPacket ColorPacket)
  28. {
  29.   filter_input = ColorPacket;
  30.   switch (m_pAtmoConfig->getLiveViewFilterMode())
  31.   {
  32.     case afmNoFilter:
  33.          filter_output = filter_input;
  34.     break;
  35.     case afmCombined:
  36.          MeanFilter(false);
  37.     break;
  38.     case afmPercent:
  39.          PercentFilter(false);
  40.     break;
  41.     default:
  42.          filter_output = filter_input;
  43.     break;
  44.   }
  45.   return filter_output;
  46. }
  47. void CAtmoOutputFilter::PercentFilter(ATMO_BOOL init)
  48. {
  49.   // last values needed for the percentage filter
  50.   static tColorPacket filter_output_old;
  51.   if (init) // Initialization
  52.   {
  53.     memset(&filter_output_old, 0, sizeof(filter_output_old));
  54.     return;
  55.   }
  56.   int percentNew = this->m_pAtmoConfig->getLiveViewFilter_PercentNew();
  57.   for (int ch = 0; ch < ATMO_NUM_CHANNELS; ch++)
  58.   {
  59. filter_output.channel[ch].r = (filter_input.channel[ch].r *
  60.          (100-percentNew) + filter_output_old.channel[ch].r * percentNew) / 100;
  61.     filter_output.channel[ch].g = (filter_input.channel[ch].g *
  62.          (100-percentNew) + filter_output_old.channel[ch].g * percentNew) / 100;
  63. filter_output.channel[ch].b = (filter_input.channel[ch].b *
  64.          (100-percentNew) + filter_output_old.channel[ch].b * percentNew) / 100;
  65.   }
  66.   filter_output_old = filter_output;
  67. }
  68. void CAtmoOutputFilter::MeanFilter(ATMO_BOOL init)
  69. {
  70.   // needed vor the running mean value filter
  71.   static tColorPacketLongInt mean_sums;
  72.   static tColorPacket mean_values;
  73.   // needed for the percentage filter
  74.   static tColorPacket filter_output_old;
  75.   static int filter_length_old;
  76.   char reinitialize = 0;
  77.   long int tmp;
  78.   if (init) // Initialization
  79.   {
  80.     memset(&filter_output_old, 0, sizeof(filter_output_old));
  81.     memset(&mean_sums, 0, sizeof(mean_sums));
  82.     memset(&mean_values, 0, sizeof(mean_values));
  83.     return;
  84.   }
  85.   int AtmoSetup_Filter_MeanLength = m_pAtmoConfig->getLiveViewFilter_MeanLength();
  86.   int AtmoSetup_Filter_PercentNew = m_pAtmoConfig->getLiveViewFilter_PercentNew();
  87.   int AtmoSetup_Filter_MeanThreshold = m_pAtmoConfig->getLiveViewFilter_MeanThreshold();
  88.   // if filter_length has changed
  89.   if (filter_length_old != AtmoSetup_Filter_MeanLength)
  90.   {
  91.     // force reinitialization of the filter
  92.     reinitialize = 1;
  93.   }
  94.   filter_length_old = AtmoSetup_Filter_MeanLength;
  95.   if (filter_length_old < 20) filter_length_old = 20; // avoid division by 0
  96.   for (int ch = 0; ch < ATMO_NUM_CHANNELS; ch++)
  97.   {
  98.     // calculate the mean-value filters
  99.     mean_sums.channel[ch].r +=
  100.          (long int)(filter_input.channel[ch].r - mean_values.channel[ch].r); // red
  101.     tmp = mean_sums.channel[ch].r / ((long int)filter_length_old / 20);
  102.     if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
  103.     mean_values.channel[ch].r = (unsigned char)tmp;
  104.     mean_sums.channel[ch].g +=
  105.         (long int)(filter_input.channel[ch].g - mean_values.channel[ch].g); // green
  106.     tmp = mean_sums.channel[ch].g / ((long int)filter_length_old / 20);
  107.     if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
  108.     mean_values.channel[ch].g = (unsigned char)tmp;
  109.     mean_sums.channel[ch].b +=
  110.         (long int)(filter_input.channel[ch].b - mean_values.channel[ch].b); // blue
  111.     tmp = mean_sums.channel[ch].b / ((long int)filter_length_old / 20);
  112.     if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
  113.     mean_values.channel[ch].b = (unsigned char)tmp;
  114.     // check, if there is a jump -> check if differences between actual values and filter values are too big
  115.     long int dist; // distance between the two colors in the 3D RGB space
  116.     dist = (mean_values.channel[ch].r - filter_input.channel[ch].r) *
  117.            (mean_values.channel[ch].r - filter_input.channel[ch].r) +
  118.            (mean_values.channel[ch].g - filter_input.channel[ch].g) *
  119.            (mean_values.channel[ch].g - filter_input.channel[ch].g) +
  120.            (mean_values.channel[ch].b - filter_input.channel[ch].b) *
  121.            (mean_values.channel[ch].b - filter_input.channel[ch].b);
  122.     /*
  123.        if (dist > 0) { dist = (long int)sqrt((double)dist); }
  124.        avoid sqrt(0) (TODO: necessary?)
  125.        I think its cheaper to calculate the square of something ..? insteas geting the square root?
  126.     */
  127.     double distMean = ((double)AtmoSetup_Filter_MeanThreshold * 3.6f);
  128.     distMean = distMean * distMean;
  129.     /*
  130.       compare calculated distance with the filter threshold
  131.      if ((dist > (long int)((double)AtmoSetup.Filter_MeanThreshold * 3.6f)) || ( reinitialize == 1))
  132.    */
  133. if ((dist > distMean) || ( reinitialize == 1))
  134.     {
  135.       // filter jump detected -> set the long filters to the result of the short filters
  136.       filter_output.channel[ch] = mean_values.channel[ch] = filter_input.channel[ch];
  137.       mean_sums.channel[ch].r = filter_input.channel[ch].r *
  138.                                 (filter_length_old / 20);
  139.       mean_sums.channel[ch].g = filter_input.channel[ch].g *
  140.                                 (filter_length_old / 20);
  141.       mean_sums.channel[ch].b = filter_input.channel[ch].b *
  142.                                 (filter_length_old / 20);
  143.     }
  144.     else
  145.     {
  146.       // apply an additional percent filter and return calculated values
  147.   filter_output.channel[ch].r = (mean_values.channel[ch].r *
  148.           (100-AtmoSetup_Filter_PercentNew) +
  149.           filter_output_old.channel[ch].r * AtmoSetup_Filter_PercentNew) / 100;
  150.   filter_output.channel[ch].g = (mean_values.channel[ch].g *
  151.           (100-AtmoSetup_Filter_PercentNew) +
  152.           filter_output_old.channel[ch].g * AtmoSetup_Filter_PercentNew) / 100;
  153.   filter_output.channel[ch].b = (mean_values.channel[ch].b *
  154.           (100-AtmoSetup_Filter_PercentNew) +
  155.           filter_output_old.channel[ch].b * AtmoSetup_Filter_PercentNew) / 100;
  156.     }
  157.   }
  158.   filter_output_old = filter_output;
  159. }