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;
}
DWORD CAtmoLiveView::Execute(void)
{
#if defined(_ATMO_VLC_PLUGIN_)
	vlc_object_t *m_pLog = m_pAtmoDynData->getAtmoFilter();
	mtime_t ticks;
	mtime_t t;
	mtime_t packet_time;
#else
	DWORD ticks;
	DWORD t;
	DWORD packet_time;
#endif
	int i_frame_counter = -1;

	pColorPacket ColorPacket;
	pColorPacket PreviousPacket = NULL;

	CAtmoConnection *pAtmoConnection = this->m_pAtmoDynData->getAtmoConnection();
	if((pAtmoConnection == NULL) || (pAtmoConnection->isOpen() == ATMO_FALSE)) return 0;

	CAtmoConfig *pAtmoConfig = this->m_pAtmoDynData->getAtmoConfig();

	/*
	this object does post processing of the pixel data
	like jump /scenechange detection fading over the colors
	*/
	CAtmoOutputFilter *filter = new CAtmoOutputFilter( this->m_pAtmoDynData->getAtmoConfig() );
	CAtmoPacketQueue *pPacketQueue = this->m_pAtmoDynData->getLivePacketQueue();

	int frameDelay = pAtmoConfig->getLiveView_FrameDelay();

#if defined(_ATMO_VLC_PLUGIN_)
	/*
	because time function of vlc are working with us values instead of ms
	*/
	frameDelay = frameDelay * 1000;
#endif

	/*
	wait for the first frame to go in sync with the other thread
	*/
	t = get_time1;

	if( pPacketQueue->WaitForNextPacket(3000) )
	{
		if( frameDelay > 0 )
			do_sleep( frameDelay );
#if defined(_ATMO_VLC_PLUGIN_)
		msg_Dbg( m_pLog, "First Packet got %"PRId64" ms", (get_time1 - t) / 1000  );
#endif
	}

	while(this->m_bTerminated == ATMO_FALSE)
	{
		i_frame_counter++;
		if(i_frame_counter == 50) i_frame_counter = 0;

		/* grab current Packet from InputQueue (working as FIFO)! */
#if defined(_ATMO_VLC_PLUGIN_)
		ColorPacket = pPacketQueue->GetNextPacket(get_time1 - frameDelay, (i_frame_counter == 0), m_pLog, packet_time);
#else
		ColorPacket = pPacketQueue->GetNextPacket(get_time1 - frameDelay, (i_frame_counter == 0), packet_time);
#endif
		if(ColorPacket)
		{
			/*
			create a packet copy - for later reuse if the input is slower than 25fps
			*/
			if(PreviousPacket && (PreviousPacket->numColors == ColorPacket->numColors))
				CopyColorPacket(ColorPacket, PreviousPacket)
			else 
			{
				delete (char *)PreviousPacket;
				DupColorPacket(PreviousPacket, ColorPacket )
			}
		} 
		else 
		{
			/*
			packet queue was empty for the given point of time
			*/
			if(i_frame_counter == 0)
			{
#if defined(_ATMO_VLC_PLUGIN_)
				msg_Dbg( m_pLog, "wait for delayed packet..." );
#endif
				t = get_time1;
				if( pPacketQueue->WaitForNextPacket(200) )
				{
					if( frameDelay > 0 )
						do_sleep( frameDelay );
#if defined(_ATMO_VLC_PLUGIN_)
					msg_Dbg( m_pLog, "got delayed packet %"PRId64" ms", (mdate() - t) / 1000  );
#endif
					continue;
				}
			}
			/*
			reuse previous color packet
			*/
			DupColorPacket(ColorPacket, PreviousPacket)
		}

		ticks = get_time1;

		if(ColorPacket)
		{
			/* pass it through the outputfilters! */
			// Info Filtering will possible free the colorpacket and alloc a new one!
			ColorPacket = filter->Filtering(ColorPacket);

			// invert colors
			if(pAtmoConfig->isUseinvert())
				ColorPacket = CAtmoTools::Applyinvert(pAtmoConfig, ColorPacket);

			/* apply gamma correction - only if the hardware isnt capable doing this */
			ColorPacket = CAtmoTools::ApplyGamma(pAtmoConfig, ColorPacket);

			// load color correction from Kodak 3D-Lut file
			if(pAtmoConfig->isUse3dlut() && pAtmoConfig->m_3dlut)
				ColorPacket = CAtmoTools::Apply3dlut(pAtmoConfig, ColorPacket);

			// our own trilinear CMS
			if(pAtmoConfig->isUseColorKWhiteAdj())
				ColorPacket = CAtmoTools::ApplyColorK(pAtmoConfig, ColorPacket);

			// apply white calibration - only if it is not done by the hardware
			if((pAtmoConfig->isUseSoftwareWhiteAdj()))//&&(!pAtmoConfig->isUseColorKWhiteAdj()))
				ColorPacket = CAtmoTools::WhiteCalibration(pAtmoConfig, ColorPacket);

			//Sensitivity
			ColorPacket = CAtmoTools::ApplySens(pAtmoConfig, ColorPacket);
			/* send color data to the the hardware... */
			try
			{
				pAtmoConnection->SendData(ColorPacket);
				delete (char *)ColorPacket;
			}
			catch(...)
			{
				delete (char *)ColorPacket;
			}
		}

		/*
		calculate RunTime of thread abbove (doesn't work well - so
		this threads comes out of sync with Image producer and the
		framerate (25fps) drifts away
		*/
#if defined(_ATMO_VLC_PLUGIN_)
		ticks = ((mdate() - ticks) + 999)/1000;
#else
		ticks = GetTickCount() - ticks;
#endif
		if(ticks < 40)
		{
			if( ThreadSleep( 40 - ticks ) == ATMO_FALSE )
				break;
		}
	}
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;
}