void CAtmoColorPicker::outputColor(int red,int green,int blue) 
{
	CAtmoConnection *pAtmoConnection = this->m_pAtmoDynData->getAtmoConnection();
	CAtmoConfig *pAtmoConfig = this->m_pAtmoDynData->getAtmoConfig();

	if((pAtmoConnection==NULL) || (pAtmoConnection->isOpen()==ATMO_FALSE)) return;

	pColorPacket packet;

	AllocColorPacket(packet, pAtmoConfig->getZoneCount());

	for(int i=0;i<packet->numColors;i++) 
	{
		packet->zone[i].r  = red;
		packet->zone[i].g  = green;
		packet->zone[i].b  = blue;
	}

	if(pAtmoConfig->isUseSoftwareWhiteAdj()) 
		packet = CAtmoTools::WhiteCalibration(pAtmoConfig, packet);

	packet = CAtmoTools::ApplyGamma(pAtmoConfig, packet);

	pAtmoConnection->SendData( packet );

	delete (char *)packet;
}
void CAtmoTools::ShowShutdownColor(CAtmoDynData *pDynData)
{
	pDynData->LockCriticalSection();


	CAtmoConnection *atmoConnection = pDynData->getAtmoConnection();
	CAtmoConfig *atmoConfig = pDynData->getAtmoConfig();
	if((atmoConnection != NULL) && (atmoConfig!=NULL) && atmoConfig->isSetShutdownColor()) 
	{
		int i;
		pColorPacket packet;
		AllocColorPacket(packet, atmoConfig->getZoneCount());

		// set a special color? on shutdown of the software? mostly may use black or so ...
		// if this function ist disabled ... atmo will continuing to show the last color...
		for(i = 0; i < packet->numColors; i++) 
		{
			packet->zone[i].r = atmoConfig->getShutdownColor_Red();
			packet->zone[i].g = atmoConfig->getShutdownColor_Green();
			packet->zone[i].b = atmoConfig->getShutdownColor_Blue();
		}

		packet = CAtmoTools::ApplyGamma(atmoConfig, packet);

		if(atmoConfig->isUseSoftwareWhiteAdj())
			packet = CAtmoTools::WhiteCalibration(atmoConfig, packet);

		atmoConnection->SendData(packet);

		delete (char *)packet;

	}

	pDynData->UnLockCriticalSection();
}
STDMETHODIMP CAtmoRemoteControlImplEx::setStaticColor(BYTE red, BYTE green, BYTE blue) {
    m_pAtmoDynData->LockCriticalSection();

    CAtmoConnection *connection = this->m_pAtmoDynData->getAtmoConnection();
    if((connection!=NULL) && (connection->isOpen())) {

        CAtmoConfig *pConfig = m_pAtmoDynData->getAtmoConfig();
        pColorPacket newColors;
        int zoneCount = pConfig->getZoneCount();

        AllocColorPacket(newColors, zoneCount);

        for(int i=0;i<zoneCount;i++) {
            newColors->zone[i].r = red;
            newColors->zone[i].g = green;
            newColors->zone[i].b = blue;
        }

        newColors = CAtmoTools::ApplyGamma(pConfig, newColors);

        if(pConfig->isUseSoftwareWhiteAdj()) 
            newColors = CAtmoTools::WhiteCalibration(pConfig, newColors);

        connection->SendData(newColors);

        delete (char *)newColors;
    }

    this->m_pAtmoDynData->UnLockCriticalSection();
    return S_OK;
}
Example #4
0
pColorPacket CAtmoOutputFilter::PercentFilter(pColorPacket filter_input, ATMO_BOOL init)
{
  // last values needed for the percentage filter
  if (init) // Initialization
  {
    if(m_percent_filter_output_old)
       delete[] m_percent_filter_output_old;
    m_percent_filter_output_old = NULL;
    return(NULL);
  }

  if(!m_percent_filter_output_old || (m_percent_filter_output_old->numColors!=filter_input->numColors)) {
     delete[] m_percent_filter_output_old;
     AllocColorPacket(m_percent_filter_output_old, filter_input->numColors);
     ZeroColorPacket(m_percent_filter_output_old);
  }

  int percentNew = this->m_pAtmoConfig->getLiveViewFilter_PercentNew();

  pColorPacket filter_output;
  AllocColorPacket(filter_output, filter_input->numColors);

  for (int zone = 0; zone < filter_input->numColors; zone++)
  {
	filter_output->zone[zone].r = (filter_input->zone[zone].r *
         (100-percentNew) + m_percent_filter_output_old->zone[zone].r * percentNew) / 100;
	
    filter_output->zone[zone].g = (filter_input->zone[zone].g *
         (100-percentNew) + m_percent_filter_output_old->zone[zone].g * percentNew) / 100;

	filter_output->zone[zone].b = (filter_input->zone[zone].b *
         (100-percentNew) + m_percent_filter_output_old->zone[zone].b * percentNew) / 100;
  }

  CopyColorPacket( filter_output, m_percent_filter_output_old );

  delete[] filter_input;

  return filter_output;
}
Example #5
0
pColorPacket CAtmoOutputFilter::MeanFilter(pColorPacket filter_input, ATMO_BOOL init)
{
  // needed vor the running mean value filter

  // needed for the percentage filter
  static int filter_length_old;
  char reinitialize = 0;
  long int tmp;
  pColorPacket filter_output;

  if (init) // Initialization
  {
    if(m_mean_filter_output_old)
       delete[] m_mean_filter_output_old;
    m_mean_filter_output_old = NULL;

    if(m_mean_values)
       delete[] m_mean_values;
    m_mean_values = NULL;

    if(m_mean_sums)
       delete[] m_mean_sums;
    m_mean_sums = NULL;
    return (NULL);
  }

  if(!m_mean_filter_output_old || (m_mean_filter_output_old->numColors!=filter_input->numColors)) {
        delete[] m_mean_filter_output_old;
        AllocColorPacket(m_mean_filter_output_old, filter_input->numColors);
        ZeroColorPacket(m_mean_filter_output_old);
  }

  if(!m_mean_values || (m_mean_values->numColors!=filter_input->numColors)) {
        delete[] m_mean_values;
        AllocColorPacket(m_mean_values, filter_input->numColors);
        ZeroColorPacket(m_mean_values);
  }

  if(!m_mean_sums || (m_mean_sums->numColors!=filter_input->numColors)) {
        delete[] m_mean_sums;
        AllocLongColorPacket(m_mean_sums, filter_input->numColors);
        ZeroLongColorPacket(m_mean_sums);
  }

  AllocColorPacket(filter_output, filter_input->numColors);


  int AtmoSetup_Filter_MeanLength = m_pAtmoConfig->getLiveViewFilter_MeanLength();
  int AtmoSetup_Filter_PercentNew = m_pAtmoConfig->getLiveViewFilter_PercentNew();
  int AtmoSetup_Filter_MeanThreshold = m_pAtmoConfig->getLiveViewFilter_MeanThreshold();

  // if filter_length has changed
  if (filter_length_old != AtmoSetup_Filter_MeanLength)
  {
    // force reinitialization of the filter
    reinitialize = 1;
  }
  filter_length_old = AtmoSetup_Filter_MeanLength;

  if (filter_length_old < 20) filter_length_old = 20; // avoid division by 0

  for (int zone = 0; zone < filter_input->numColors; zone++)
  {
    // calculate the mean-value filters
      m_mean_sums->longZone[zone].r +=
        (long int)(filter_input->zone[zone].r - m_mean_values->zone[zone].r); // red
    tmp = m_mean_sums->longZone[zone].r / ((long int)filter_length_old / 20);
    if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
    m_mean_values->zone[zone].r = (unsigned char)tmp;

    m_mean_sums->longZone[zone].g +=
        (long int)(filter_input->zone[zone].g - m_mean_values->zone[zone].g); // green
    tmp = m_mean_sums->longZone[zone].g / ((long int)filter_length_old / 20);
    if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
    m_mean_values->zone[zone].g = (unsigned char)tmp;

    m_mean_sums->longZone[zone].b +=
        (long int)(filter_input->zone[zone].b - m_mean_values->zone[zone].b); // blue
    tmp = m_mean_sums->longZone[zone].b / ((long int)filter_length_old / 20);
    if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
    m_mean_values->zone[zone].b = (unsigned char)tmp;

    // check, if there is a jump -> check if differences between actual values and filter values are too big

    long int dist; // distance between the two colors in the 3D RGB space
    dist = (m_mean_values->zone[zone].r - filter_input->zone[zone].r) *
           (m_mean_values->zone[zone].r - filter_input->zone[zone].r) +
           (m_mean_values->zone[zone].g - filter_input->zone[zone].g) *
           (m_mean_values->zone[zone].g - filter_input->zone[zone].g) +
           (m_mean_values->zone[zone].b - filter_input->zone[zone].b) *
           (m_mean_values->zone[zone].b - filter_input->zone[zone].b);

    /*
       if (dist > 0) { dist = (long int)sqrt((double)dist); }
       avoid sqrt(0) (TODO: necessary?)
       I think its cheaper to calculate the square of something ..? insteas geting the square root?
    */
    double distMean = ((double)AtmoSetup_Filter_MeanThreshold * 3.6f);
    distMean = distMean * distMean;

    /*
      compare calculated distance with the filter threshold
  	  if ((dist > (long int)((double)AtmoSetup.Filter_MeanThreshold * 3.6f)) || ( reinitialize == 1))
   */

	if ((dist > distMean) || ( reinitialize == 1))
    {
      // filter jump detected -> set the long filters to the result of the short filters
      filter_output->zone[zone] = m_mean_values->zone[zone] = filter_input->zone[zone];

      m_mean_sums->longZone[zone].r = filter_input->zone[zone].r *
                                (filter_length_old / 20);
      m_mean_sums->longZone[zone].g = filter_input->zone[zone].g *
                                (filter_length_old / 20);
      m_mean_sums->longZone[zone].b = filter_input->zone[zone].b *
                                (filter_length_old / 20);
    }
    else
    {
      // apply an additional percent filter and return calculated values

	  filter_output->zone[zone].r = (m_mean_values->zone[zone].r *
          (100-AtmoSetup_Filter_PercentNew) +
          m_mean_filter_output_old->zone[zone].r * AtmoSetup_Filter_PercentNew) / 100;

	  filter_output->zone[zone].g = (m_mean_values->zone[zone].g *
          (100-AtmoSetup_Filter_PercentNew) +
          m_mean_filter_output_old->zone[zone].g * AtmoSetup_Filter_PercentNew) / 100;

	  filter_output->zone[zone].b = (m_mean_values->zone[zone].b *
          (100-AtmoSetup_Filter_PercentNew) +
          m_mean_filter_output_old->zone[zone].b * AtmoSetup_Filter_PercentNew) / 100;
    }
  }

  CopyColorPacket(filter_output, m_mean_filter_output_old);

  delete[] filter_input;

  return(filter_output);
}
EffectMode CAtmoTools::SwitchEffect(CAtmoDynData *pDynData, EffectMode newEffectMode)
{
	// may need a critical section??
	if(pDynData == NULL) 
	{
		return emUndefined;
	}
	pDynData->LockCriticalSection();

	CAtmoConfig *atmoConfig = pDynData->getAtmoConfig();
	if(atmoConfig == NULL) 
	{
		pDynData->UnLockCriticalSection();
		return emUndefined;
	}
	CAtmoConnection *atmoConnection = pDynData->getAtmoConnection();

	EffectMode oldEffectMode = atmoConfig->getEffectMode();
	CThread *currentEffect = pDynData->getEffectThread();
	CAtmoInput *currentInput = pDynData->getLiveInput();
	CAtmoPacketQueue *currentPacketQueue = pDynData->getLivePacketQueue();


	if(oldEffectMode == emLivePicture)
	{
		/* in case of disabling the live mode
		first we have to stop the input
		then the effect thread!
		*/
		if(currentInput != NULL) 
		{
			pDynData->setLiveInput( NULL );
			currentInput->Close();
			delete currentInput;
			currentInput = NULL;
		}
	}

	// stop and delete/cleanup current Effect Thread...
	pDynData->setEffectThread( NULL );
	if(currentEffect != NULL)
	{
		currentEffect->Terminate();
		delete currentEffect;
		currentEffect = NULL;
	}

	if(oldEffectMode == emLivePicture) 
	{
		/*
		and last we kill the PacketQueue used for communication between the threads
		*/
		pDynData->setLivePacketQueue( NULL );
		delete currentPacketQueue;
		currentPacketQueue = NULL;
	}

	if((atmoConnection!=NULL) && (atmoConnection->isOpen()==ATMO_TRUE))
	{
		// neuen EffectThread nur mit aktiver Connection starten...

		switch(newEffectMode) 
		{
		case emUndefined: // do nothing also in that case (avoid compiler warning)
			break;
		case emDisabled:
			{
				// get values from config - and put them to all channels?
				pColorPacket packet;
				AllocColorPacket(packet, atmoConfig->getZoneCount());

				for(int i=0; i < packet->numColors; i++)
				{
					packet->zone[i].r = 0;
					packet->zone[i].g = 0;
					packet->zone[i].b = 0;
				}

				atmoConnection->SendData( packet );
				atmoConnection->SendData( packet );

				delete (char *)packet;

				break;
			}


		case emStaticColor: 
			{
				// get values from config - and put them to all channels?
				pColorPacket packet;
				AllocColorPacket(packet, atmoConfig->getZoneCount());
				for(int i=0; i < packet->numColors; i++){
					packet->zone[i].r = atmoConfig->getStaticColor_Red();
					packet->zone[i].g = atmoConfig->getStaticColor_Green();
					packet->zone[i].b = atmoConfig->getStaticColor_Blue();
				}

				packet = CAtmoTools::ApplyGamma( atmoConfig, packet );

				if(atmoConfig->isUseSoftwareWhiteAdj())
					packet = CAtmoTools::WhiteCalibration(atmoConfig, packet);

				atmoConnection->SendData( packet );
				atmoConnection->SendData( packet );

				delete (char *)packet;

				break;
			}

		case emLivePicture: 
			{
				currentEffect = new CAtmoLiveView(pDynData);

#if !defined(_ATMO_VLC_PLUGIN_)
				CAtmoPacketQueueStatus *packetMon = NULL;
				if(atmoConfig->getShow_statistics())
				{
					packetMon = new CAtmoPacketQueueStatus(pDynData->getAppHinstance(), (HWND)NULL);
					packetMon->createWindow();
					packetMon->showWindow(SW_SHOW);
				}
				currentPacketQueue = new CAtmoPacketQueue(packetMon);
				pDynData->setLivePictureSource(lpsScreenCapture);
				//Atmo liveview option GDi <Win7 / DekstopDuplication >Win8
				int AtmoSetup_Mode = atmoConfig->getLiveView_Mode();
				if (AtmoSetup_Mode == 1)
				{
					 currentInput = new CAtmoDesktopDuplicationCaptureInput( pDynData );
				}
				else
				{
					 currentInput = new CAtmoGdiDisplayCaptureInput( pDynData );
				}

#else
				currentPacketQueue = new CAtmoPacketQueue();
				pDynData->setLivePictureSource(lpsExtern);
				currentInput = new CAtmoExternalCaptureInput( pDynData );
#endif
				break;
			}

#if !defined(_ATMO_VLC_PLUGIN_)
		case emColorChange:
			currentEffect = new CAtmoColorChanger(atmoConnection, atmoConfig);
			break;

		case emLrColorChange:
			currentEffect = new CAtmoLeftRightColorChanger(atmoConnection, atmoConfig);
			break;
#endif
		}

	}

	atmoConfig->setEffectMode( newEffectMode );

	pDynData->setLivePacketQueue( currentPacketQueue );
	pDynData->setEffectThread( currentEffect );
	pDynData->setLiveInput( currentInput );

	if(currentEffect != NULL)
		currentEffect->Run();
	if(currentInput != NULL)
		currentInput->Open();

	pDynData->UnLockCriticalSection();
	return oldEffectMode;
}
pColorPacket CAtmoColorCalculator::AnalyzeHSV(tHSVColor *HSV_Img)
{
  int i; // counter

  int AtmoSetup_EdgeWeighting  = m_pAtmoConfig->getLiveView_EdgeWeighting();
  int AtmoSetup_WidescreenMode = m_pAtmoConfig->getLiveView_WidescreenMode();
  int AtmoSetup_DarknessLimit  = m_pAtmoConfig->getLiveView_DarknessLimit();
  int AtmoSetup_BrightCorrect  = m_pAtmoConfig->getLiveView_BrightCorrect();
  int AtmoSetup_SatWinSize     = m_pAtmoConfig->getLiveView_SatWinSize();
  int AtmoSetup_NumZones       = m_pAtmoConfig->getZoneCount();
  tHSVColor *temp_Img;

  if(AtmoSetup_NumZones != m_LastNumZones)
  {
     delete[] m_Weight;
     delete[] m_hue_hist;
     delete[] m_windowed_hue_hist;
     delete[] m_most_used_hue_last;
     delete[] m_most_used_hue;
     delete[] m_sat_hist;
     delete[] m_windowed_sat_hist;
     delete[] m_most_used_sat;
     delete[] m_Zone_Weights;
     delete[] m_average_v;
     delete[] m_average_counter;

     m_Weight              = new int[AtmoSetup_NumZones * IMAGE_SIZE];
     m_Zone_Weights        = new int*[AtmoSetup_NumZones];
     for(int i = 0; i < AtmoSetup_NumZones; i++)
         m_Zone_Weights[i] = &m_Weight[i * IMAGE_SIZE];

     m_hue_hist            = new long int[(h_MAX+1) * AtmoSetup_NumZones];
     m_windowed_hue_hist   = new long int[(h_MAX+1) * AtmoSetup_NumZones];

     m_most_used_hue_last  = new int[AtmoSetup_NumZones];
     m_most_used_hue       = new int[AtmoSetup_NumZones];
     memset( m_most_used_hue_last, 0, sizeof(int) * AtmoSetup_NumZones);

     m_sat_hist           = new long int[(s_MAX+1) * AtmoSetup_NumZones];
     m_windowed_sat_hist  = new long int[(s_MAX+1) * AtmoSetup_NumZones];
     m_most_used_sat      = new int[AtmoSetup_NumZones];

     m_average_v         = new long int[AtmoSetup_NumZones];
     m_average_counter   = new int[AtmoSetup_NumZones];

     m_LastNumZones = AtmoSetup_NumZones;
  }


  // calculate only if setup has changed
  if ((AtmoSetup_EdgeWeighting != m_LastEdgeWeighting) ||
      (AtmoSetup_WidescreenMode != m_LastWidescreenMode) ||
      (m_pAtmoConfig->getZonesTopCount() != m_LastLayout_TopCount) ||
      (m_pAtmoConfig->getZonesBottomCount() != m_LastLayout_BottomCount) ||
      (m_pAtmoConfig->getZonesLRCount() !=  m_LastLayout_LRCount) ||
      (m_pAtmoConfig->m_UpdateEdgeWeightningFlag != 0)
     )
  {

      for(i = 0 ;i < AtmoSetup_NumZones; i++) {
          CAtmoZoneDefinition *pZoneDef = m_pAtmoConfig->getZoneDefinition(i);
          if(pZoneDef)
          {
             pZoneDef->UpdateWeighting(m_Zone_Weights[i],
                                                              AtmoSetup_WidescreenMode,
                                                              AtmoSetup_EdgeWeighting);
#ifdef _debug_zone_weight_
             char filename[128];
             sprintf(filename, "zone_%d_gradient_debug.bmp",i);
             pZoneDef->SaveZoneBitmap( filename );
             sprintf(filename, "zone_%d_weight_%d_debug.bmp",i,AtmoSetup_EdgeWeighting);
             pZoneDef->SaveWeightBitmap(filename, m_Zone_Weights[i] );
#endif
          }

     }
     m_pAtmoConfig->m_UpdateEdgeWeightningFlag = 0;

     m_LastEdgeWeighting      = AtmoSetup_EdgeWeighting;
     m_LastWidescreenMode     = AtmoSetup_WidescreenMode;
     m_LastLayout_TopCount    = m_pAtmoConfig->getZonesTopCount();
     m_LastLayout_BottomCount = m_pAtmoConfig->getZonesBottomCount();
     m_LastLayout_LRCount     = m_pAtmoConfig->getZonesLRCount();
  }

  AtmoSetup_DarknessLimit = AtmoSetup_DarknessLimit * 10;


  /***************************************************************************/
  /* Hue                                                                     */
  /***************************************************************************/
  /*----------------------------*/
  /* hue histogram builtup      */
  /*----------------------------*/
  // HSV histogram
  // long int hue_hist[CAP_MAX_NUM_ZONES][h_MAX+1];

  // average brightness (value)
  // m_average_v m_average_counter

  // clean histogram --> calloc
  memset(m_hue_hist, 0, sizeof(long int) * (h_MAX+1) * AtmoSetup_NumZones);
  memset(m_average_v, 0, sizeof(long int) * AtmoSetup_NumZones);
  memset(m_average_counter, 0, sizeof(int) * AtmoSetup_NumZones);

  temp_Img = HSV_Img;
  i = 0;
  for (int row = 0; row < CAP_HEIGHT; row++)
  {
    for (int column = 0; column < CAP_WIDTH; column++)
    {
      // forget black bars: perform calculations only if pixel has some luminosity
	  if ((*temp_Img).v > AtmoSetup_DarknessLimit)
      {
        // builtup histogram for the x Zones of the Display
        for (int zone = 0; zone < AtmoSetup_NumZones; zone++)
        {
          // Add weight to channel
         // Weight(zone, pixel_nummer) m_Weight[((zone) * (IMAGE_SIZE)) + (pixel_nummer)]
         // m_hue_hist[zone*(h_MAX+1) + HSV_Img[i].h] += m_Zone_Weights[zone][i] * HSV_Img[i].v;
            m_hue_hist[zone*(h_MAX+1) + (*temp_Img).h] += m_Zone_Weights[zone][i] * temp_Img->v;

            if(m_Zone_Weights[zone][i] > 0) {
               m_average_v[zone] += temp_Img->v;
               m_average_counter[zone]++;
            }

        }
        // calculate brightness average
      }
      temp_Img++;
      i++;
    }
  }

  /*----------------------------*/
  /* hue histogram windowing    */
  /*----------------------------*/
  // windowed HSV histogram
  // long int w_hue_hist[CAP_MAX_NUM_ZONES][h_MAX+1]; -> m_windowed_hue_hist
  // clean windowed histogram
  memset(m_windowed_hue_hist, 0, sizeof(long int) * (h_MAX+1) * AtmoSetup_NumZones);
  // steps in each direction; eg. 2 => -2 -1 0 1 2 windowing
  int hue_windowsize = m_pAtmoConfig->getLiveView_HueWinSize();

  for (i = 0; i < h_MAX+1; i++) // walk through histogram [0;h_MAX]
  {
    // windowing from -hue_windowsize -> +hue_windowsize
    for (int mywin = -hue_windowsize; mywin < hue_windowsize+1; mywin++)
    {
      // addressed histogram candlestick
      int myidx = i + mywin;

      // handle beginning of windowing -> roll back
      if (myidx < 0)     { myidx = myidx + h_MAX + 1; }

      // handle end of windowing -> roll forward
      if (myidx > h_MAX) { myidx = myidx - h_MAX - 1; }

      // Apply windowing to all x zones
      for (int zone = 0; zone < AtmoSetup_NumZones; zone++)
      {
        // apply lite triangular window design with gradient of 10% per discrete step
        m_windowed_hue_hist[(zone * (h_MAX+1)) + i] += m_hue_hist[(zone * (h_MAX+1)) + myidx] * ((hue_windowsize+1)-abs(mywin)); // apply window
      }
    }
  }

  /*--------------------------------------*/
  /* analyze histogram for most used hue  */
  /*--------------------------------------*/
  // index of last maximum
  // static int most_used_hue_last[CAP_MAX_NUM_ZONES] = {0, 0, 0, 0, 0}; --> m_most_used_hue_last

  // resulting hue for each channel
  //int most_used_hue[CAP_MAX_NUM_ZONES]; --> m_most_used_hue

  FindMostUsed(AtmoSetup_NumZones, m_most_used_hue, m_windowed_hue_hist);
  for (int zone = 0; zone < AtmoSetup_NumZones; zone++)
  {
    float percent = (float)m_windowed_hue_hist[zone * (h_MAX+1) + m_most_used_hue_last[zone]] / (float)m_windowed_hue_hist[zone * (h_MAX+1) + m_most_used_hue[zone]];
    if (percent > 0.93f) // less than 7% difference?
        m_most_used_hue[zone] = m_most_used_hue_last[zone]; // use last index
     else
        m_most_used_hue_last[zone] = m_most_used_hue[zone];
  }

  /*
  memset(m_most_used_hue, 0, sizeof(int) * AtmoSetup_NumZones);

  for (int zone = 0; zone < AtmoSetup_NumZones; zone++)
  {
    long int value = 0;
    for (i = 0; i < h_MAX+1; i++) // walk through histogram
    {
      long int tmp = m_windowed_hue_hist[ (zone * (h_MAX+1)) + i ];
      if (tmp > value) // if new value bigger then old one
      {
        m_most_used_hue[zone] = i;     // remember index
        value = tmp; // w_hue_hist[zone][i]; // and value
      }
    }

    float percent = (float)m_windowed_hue_hist[zone * (h_MAX+1) + m_most_used_hue_last[zone]] / (float)value;
    if (percent > 0.93f) // less than 7% difference?
    {
      m_most_used_hue[zone] = m_most_used_hue_last[zone]; // use last index
    }

    m_most_used_hue_last[zone] = m_most_used_hue[zone]; // save current index of most used hue
  }
  */

  /***************************************************************************/
  /* saturation                                                              */
  /***************************************************************************/
  // sat histogram
  // long int sat_hist[CAP_MAX_NUM_ZONES][s_MAX+1];  -> m_sat_hist
  // hue of the pixel we are working at
  int pixel_hue = 0;
  // clean histogram
  memset(m_sat_hist, 0, sizeof(long int) * (s_MAX+1) * AtmoSetup_NumZones);

  /*--------------------------------------*/
  /* saturation histogram builtup         */
  /*--------------------------------------*/
  i = 0;
  temp_Img = HSV_Img;
  for (int row = 0; row < CAP_HEIGHT; row++)
  {
    for (int column = 0; column < CAP_WIDTH; column++)
    {
      // forget black bars: perform calculations only if pixel has some luminosity
	  if ((*temp_Img).v > AtmoSetup_DarknessLimit)
      {
        // find histogram position for pixel
        pixel_hue = (*temp_Img).h;

        // TODO:   brightness calculation(if we require it some time)

        for (int zone = 0; zone < AtmoSetup_NumZones; zone++)
        {
          // only use pixel for histogram if hue is near most_used_hue
          if ((pixel_hue > m_most_used_hue[zone] - hue_windowsize) &&
              (pixel_hue < m_most_used_hue[zone] + hue_windowsize))
          {
            // build histogram
            // sat_hist[channel][HSV_Img[i].s] += Weight[i].channel[channel] * HSV_Img[i].v;
            m_sat_hist[zone * (s_MAX+1) + (*temp_Img).s ] += m_Zone_Weights[zone][i] * (*temp_Img).v;

          }
        }
      }
      i++;
      temp_Img++;
    }
  }

  /*--------------------------------------*/
  /* saturation histogram windowing       */
  /*--------------------------------------*/
   // windowed HSV histogram
   // long int w_sat_hist[CAP_MAX_NUM_ZONES][s_MAX+1]; --> m_windowed_sat_hist
   // clean windowed histogram
   memset(m_windowed_sat_hist, 0, sizeof(long int) * (s_MAX+1) * AtmoSetup_NumZones);
   // steps in each direction; eg. 2 => -2 -1 0 1 2 windowing
   int sat_windowsize = AtmoSetup_SatWinSize;

   // walk through histogram [0;h_MAX]
   for (i = 0; i < s_MAX + 1; i++)
   {
     // windowing from -hue_windowsize -> +hue_windowsize
     for (int mywin = -sat_windowsize; mywin < sat_windowsize+1; mywin++)
     {
       // addressed histogram candlestick
       int myidx = i + mywin;

       // handle beginning of windowing -> roll back
       if (myidx < 0)     { myidx = myidx + s_MAX + 1; }

       // handle end of windowing -> roll forward
       if (myidx > h_MAX) { myidx = myidx - s_MAX - 1; }

       for (int zone = 0; zone < AtmoSetup_NumZones; zone++)
       {
         /*
            apply lite triangular window design with
            gradient of 10% per discrete step
         */
         /*
         w_sat_hist[channel][i] += sat_hist[channel][myidx] *
                                  ((sat_windowsize+1)-abs(mywin)); // apply window
         */
         m_windowed_sat_hist[zone * (s_MAX+1) + i] += m_sat_hist[zone* (h_MAX+1) + myidx] *
                                  ((sat_windowsize+1)-abs(mywin)); // apply window
       }
     }
   }

  /*--------------------------------------*/
  /* analyze histogram for most used sat  */
  /*--------------------------------------*/
   // resulting sat (most_used_hue) for each channel
  // int most_used_sat[CAP_MAX_NUM_ZONES];->m_most_used_sat

  FindMostUsed(AtmoSetup_NumZones, m_most_used_sat, m_windowed_sat_hist);
  /*
  memset(m_most_used_sat, 0, sizeof(int) * AtmoSetup_NumZones);

  for (int zone = 0; zone < AtmoSetup_NumZones; zone++)
  {
    int value = 0;
    // walk trough histogram
    for (i = 0; i < s_MAX+1; i++)
    {
      // if new value bigger then old one
      int tmp = m_windowed_sat_hist[zone * (s_MAX+1) + i];
      // if (w_sat_hist[channel][i] > value)
      if (tmp > value)
      {
        // remember index
        m_most_used_sat[zone] = i;
        // and value
        value = tmp;
      }
    }
  }
  */


  /*----------------------------------------------------------*/
  /* calculate average brightness within HSV image            */
  /* uniform Brightness for all channels is calculated        */
  /*----------------------------------------------------------*/
  /* code integrated into "hue histogram builtup" to save some looping time!
  int l_counter = 0;
  // average brightness (value)
  long int value_avg = 0;
  i = 0;
  for (int row = 0; row < CAP_HEIGHT; row++)
  {
    for (int column = 0; column < CAP_WIDTH; column++)
    {
      // find average value: only use bright pixels for luminance average
	  if (HSV_Img[i].v > AtmoSetup_DarknessLimit)
      {
        // build brightness average
        value_avg += HSV_Img[i].v;
        l_counter++;
      }
      i++;
    }
  }
  // calculate brightness average
  if (l_counter > 0) { value_avg = value_avg / l_counter; }
    else { value_avg = AtmoSetup_DarknessLimit; }

  */


  /*----------------------------*/
  /* adjust and copy results    */
  /*----------------------------*/
  tHSVColor hsv_pixel;
  // storage container for resulting RGB values
  pColorPacket output_colors;
  AllocColorPacket(output_colors, AtmoSetup_NumZones);

  // adjust brightness
//  int new_value = (int) ((float)value_avg * ((float)AtmoSetup_BrightCorrect / 100.0));
//  if (new_value > 255) new_value = 255;  // ensure brightness isn't set too high
//  hsv_pixel.v = (unsigned char)new_value;

  /*
  // calculate brightness average
  for(int zone = 0; zone < AtmoSetup_NumZones; zone++) {
      if(m_average_counter[zone] > 0)
          m_average_v[zone] = m_average_v[zone] / m_average_counter[zone]
      else
          m_average_v[zone] = AtmoSetup_DarknessLimit;
  }

  */

  for (int zone = 0; zone < AtmoSetup_NumZones; zone++)
  {
    if(m_average_counter[zone] > 0)
       m_average_v[zone] = m_average_v[zone] / m_average_counter[zone];
    else
       m_average_v[zone] = AtmoSetup_DarknessLimit;

    m_average_v[zone] = (int)((float)m_average_v[zone] * ((float)AtmoSetup_BrightCorrect / 100.0));

    hsv_pixel.v = (unsigned char)ATMO_MAX(ATMO_MIN(m_average_v[zone],255),0);
    hsv_pixel.h = m_most_used_hue[zone];
    hsv_pixel.s = m_most_used_sat[zone];

    // convert back to rgb
    output_colors->zone[zone] = HSV2RGB(hsv_pixel);
  }


  return output_colors;
}
Example #8
0
void CAtmoBasicEffect::Interpolation(int iSteps, int iPause, pColorPacket fadeTo)
{
    int s_1;  // zählvariablen
    int	s_2;

    pColorPacket ausgabe;
    pColorPacket output;

    // Stepsize for each fading step
    float *interpolation_r = new float[fadeTo->numColors]; // Differenz zw. 2 R/G/B werten zur Interpolation
    float *interpolation_g = new float[fadeTo->numColors];
    float *interpolation_b = new float[fadeTo->numColors];

    if(!m_RGB_alt || (m_RGB_alt->numColors != fadeTo->numColors) )
    {
   	   delete (char *)m_RGB_alt; 
       m_RGB_alt=NULL;

       for ( s_1 = 0; s_1 < fadeTo->numColors ; s_1++ ) {
            interpolation_r[s_1] = (float)(fadeTo->zone[s_1].r) / (float)iSteps;
 		    interpolation_g[s_1] = (float)(fadeTo->zone[s_1].g) / (float)iSteps;
 		    interpolation_b[s_1] = (float)(fadeTo->zone[s_1].b) / (float)iSteps;
       }

    } else {
   	   for ( s_1 = 0; s_1 < fadeTo->numColors ; s_1++ ) {
            interpolation_r[s_1] = (float)(fadeTo->zone[s_1].r - m_RGB_alt->zone[s_1].r) / (float)iSteps;
 		    interpolation_g[s_1] = (float)(fadeTo->zone[s_1].g - m_RGB_alt->zone[s_1].g) / (float)iSteps;
 		    interpolation_b[s_1] = (float)(fadeTo->zone[s_1].b - m_RGB_alt->zone[s_1].b) / (float)iSteps;
       }
    }

    AllocColorPacket(ausgabe, fadeTo->numColors);

    // fading... color...
	for ( s_2 = 1; s_2<=iSteps ; s_2++ ) // anfang interpolation und ausgabe
	{
        if(m_RGB_alt)
        {
		   for(int zone = 0; zone<fadeTo->numColors; zone++) {
  			   ausgabe->zone[zone].r = m_RGB_alt->zone[zone].r + (int)((float)s_2 * interpolation_r[zone]);
			   ausgabe->zone[zone].g = m_RGB_alt->zone[zone].g + (int)((float)s_2 * interpolation_g[zone]);
  			   ausgabe->zone[zone].b = m_RGB_alt->zone[zone].b + (int)((float)s_2 * interpolation_b[zone]);
           }
        } else  {
		   for(int zone = 0; zone<fadeTo->numColors; zone++) {
  			   ausgabe->zone[zone].r = (int)((float)s_2 * interpolation_r[zone]);
			   ausgabe->zone[zone].g = (int)((float)s_2 * interpolation_g[zone]);
  			   ausgabe->zone[zone].b = (int)((float)s_2 * interpolation_b[zone]);
           }
        }
        DupColorPacket(output, ausgabe);

        output = CAtmoTools::ApplyGamma(m_AtmoConfig, output);

        if(m_AtmoConfig->isUseSoftwareWhiteAdj())
           output = CAtmoTools::WhiteCalibration(m_AtmoConfig, output);

        m_AtmoConnection->SendData(output);

        delete (char *)output;

		if(ThreadSleep(iPause) == ATMO_FALSE)
		   break;
	}	

    // save last color as start color for next run
    delete (char *)m_RGB_alt;
    delete []interpolation_r;
    delete []interpolation_g;
    delete []interpolation_b;


    m_RGB_alt = ausgabe; 
}