<commit_before>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include "stdafx.h"

#include "RhoThreadImpl.h"

namespace rho{
namespace common{
IMPLEMENT_LOGCLASS(CRhoThreadImpl,"RhoThread");

CRhoThreadImpl::CRhoThreadImpl() : m_hAwakeEvent(0), m_hThread(0)
{
	m_hAwakeEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
}

CRhoThreadImpl::~CRhoThreadImpl()
{
    if ( m_hAwakeEvent )
        ::CloseHandle(m_hAwakeEvent);
}

static DWORD WINAPI runProc(void* pv) throw()
{
	IRhoRunnable* p = static_cast<IRhoRunnable*>(pv);
	p->runObject();
#if !defined(OS_WP8)
    ::ExitThread(0);
#endif
	return 0;
}

void CRhoThreadImpl::start(IRhoRunnable* pRunnable, IRhoRunnable::EPriority ePriority)
{
    m_hThread = ::CreateThread(NULL, 0, runProc, pRunnable, 0, NULL);
    setThreadPriority(ePriority);
}

void CRhoThreadImpl::setThreadPriority(IRhoRunnable::EPriority ePriority)
{
    int nPriority = THREAD_PRIORITY_NORMAL;
    if ( ePriority == IRhoRunnable::epHigh )
        nPriority = THREAD_PRIORITY_HIGHEST;
    else if (ePriority == IRhoRunnable::epLow)
        nPriority = THREAD_PRIORITY_LOWEST;

    ::SetThreadPriority(m_hThread,nPriority);
}

void CRhoThreadImpl::stop(unsigned int nTimeoutToKillMs)
{
    stopWait();
    if ( m_hThread )
    {
        DWORD dwRes = ::WaitForSingleObject( m_hThread, nTimeoutToKillMs );
        if ( dwRes != WAIT_OBJECT_0 )
        {
            LOG(INFO) + "Terminate thread. ID: " + ::GetCurrentThreadId() + "; Result: " + dwRes;
            ::TerminateThread(m_hThread,0);
        }
        ::CloseHandle(m_hThread);
        m_hThread = null;
    }
}

int CRhoThreadImpl::wait(unsigned int nTimeoutMs)
{
    DWORD dwRes = ::WaitForSingleObject( m_hAwakeEvent, nTimeoutMs );
    if ( dwRes == WAIT_FAILED )
        LOG(ERROR) + "WaitForSingleObject failed. ID: " + ::GetCurrentThreadId() + "; Result: " + dwRes;

    return dwRes == WAIT_TIMEOUT ? 1 : 0;
}

void CRhoThreadImpl::stopWait()
{
    ::SetEvent(m_hAwakeEvent);
}

void CRhoThreadImpl::sleep(unsigned int nTimeoutMs)
{
    ::Sleep(nTimeoutMs);
}

}
}<commit_msg>Add debug Logs<commit_after>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include "stdafx.h"

#include "RhoThreadImpl.h"

namespace rho{
namespace common{
IMPLEMENT_LOGCLASS(CRhoThreadImpl,"RhoThreadWM");

CRhoThreadImpl::CRhoThreadImpl() : m_hAwakeEvent(0), m_hThread(0)
{
	LOG(INFO) + " JDP create CRhoThreadImpl(WM) object";
	m_hAwakeEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
}

CRhoThreadImpl::~CRhoThreadImpl()
{
    if ( m_hAwakeEvent )
        ::CloseHandle(m_hAwakeEvent);
}

static DWORD WINAPI runProc(void* pv) throw()
{
	IRhoRunnable* p = static_cast<IRhoRunnable*>(pv);
	p->runObject();
#if !defined(OS_WP8)
    ::ExitThread(0);
#endif
	return 0;
}

void CRhoThreadImpl::start(IRhoRunnable* pRunnable, IRhoRunnable::EPriority ePriority)
{
    m_hThread = ::CreateThread(NULL, 0, runProc, pRunnable, 0, NULL);
    setThreadPriority(ePriority);
}

void CRhoThreadImpl::setThreadPriority(IRhoRunnable::EPriority ePriority)
{
    int nPriority = THREAD_PRIORITY_NORMAL;
    if ( ePriority == IRhoRunnable::epHigh )
        nPriority = THREAD_PRIORITY_HIGHEST;
    else if (ePriority == IRhoRunnable::epLow)
        nPriority = THREAD_PRIORITY_LOWEST;

    ::SetThreadPriority(m_hThread,nPriority);
}

void CRhoThreadImpl::stop(unsigned int nTimeoutToKillMs)
{
    stopWait();
    if ( m_hThread )
    {
        DWORD dwRes = ::WaitForSingleObject( m_hThread, nTimeoutToKillMs );
        if ( dwRes != WAIT_OBJECT_0 )
        {
            LOG(INFO) + "Terminate thread. ID: " + ::GetCurrentThreadId() + "; Result: " + dwRes;
            ::TerminateThread(m_hThread,0);
        }
        ::CloseHandle(m_hThread);
        m_hThread = null;
    }
}

int CRhoThreadImpl::wait(unsigned int nTimeoutMs)
{
    DWORD dwRes = ::WaitForSingleObject( m_hAwakeEvent, nTimeoutMs );
    if ( dwRes == WAIT_FAILED )
        LOG(ERROR) + "WaitForSingleObject failed. ID: " + ::GetCurrentThreadId() + "; Result: " + dwRes;

    return dwRes == WAIT_TIMEOUT ? 1 : 0;
}

void CRhoThreadImpl::stopWait()
{
    ::SetEvent(m_hAwakeEvent);
}

void CRhoThreadImpl::sleep(unsigned int nTimeoutMs)
{
    ::Sleep(nTimeoutMs);
}

}
}
<|endoftext|>


<commit_before>#include "ComponentTransform.h"

// Constructors =================================
ComponentTransform::ComponentTransform() : Component(COMP_TRANSFORMATION)
{
	transform_matrix = math::float4x4::identity;
	position = { 0,0,0 };
	rotation_euler_angles = { 0,0,0 };
	scale = { 0,0,0 };
}

ComponentTransform::ComponentTransform(const ComponentTransform & cpy) : Component(cpy), position(cpy.position), scale(cpy.scale), rotation_euler_angles(cpy.rotation_euler_angles), transform_matrix(cpy.transform_matrix)
{

}

// Destructors ==================================
ComponentTransform::~ComponentTransform()
{

}

// Set Methods ==================================
void ComponentTransform::SetTransformation(aiMatrix4x4 trans)
{
	//Set the mathgeolib matrix from assim matrix
	float values[16] =
	{
		trans.a1, trans.a2, trans.a3, trans.a4,
		trans.b1, trans.b2, trans.b3, trans.b4,
		trans.c1, trans.c2, trans.c3, trans.c4,
		trans.d1, trans.d2, trans.d3, trans.d4
	};

	transform_matrix.Set(values);

	//Set the variables that will be shown in the UI
	math::Quat	rotation;
	transform_matrix.Decompose(position, rotation, scale);
	rotation_euler_angles = (rotation.ToEulerXYZ() * RADTODEG);
}

void ComponentTransform::SetTransformation(math::float4x4 trans)
{
	transform_matrix = trans;
	math::Quat rot;

	transform_matrix.Decompose(position, rot, scale);
	rotation_euler_angles = rot.ToEulerXYZ();
}

// Get Methods ==================================
math::float3 ComponentTransform::GetPosition() const
{
	return position;
}

// Functionality ================================
void ComponentTransform::BlitComponentInspector()
{
	ImGui::Separator();

	ImGui::Checkbox("##transform_comp", &actived);
	ImGui::SameLine();
	ImGui::TextColored(ImVec4(1.0f, 0.64f, 0.0f, 1.0f), "Transform");

	//Modified
	bool has_been_modified = false;

	//Transform Position
	ImGui::Text("Position ");
	ImGui::SameLine();
	ImGui::PushItemWidth(50);
	if (ImGui::DragFloat("X##position", &position.x, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::SameLine();
	if (ImGui::DragFloat("Y##position", &position.y, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::SameLine();
	if (ImGui::DragFloat("Z##position", &position.z, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;

	//Transform rotation
	bool has_rotate = false;
	ImGui::Text("Rotation ");
	ImGui::SameLine();
	ImGui::PushItemWidth(50);
	if (ImGui::DragFloat("X##rotation", &rotation_euler_angles.x, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::SameLine();
	if (ImGui::DragFloat("Y##rotation", &rotation_euler_angles.y, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::SameLine();
	if (ImGui::DragFloat("Z##rotation", &rotation_euler_angles.z, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;

	//Transform rotation
	bool has_scale = false;
	ImGui::Text("Scale    ");
	ImGui::SameLine();
	if (ImGui::DragFloat("X##scale", &scale.x, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::SameLine();
	if (ImGui::DragFloat("Y##scale", &scale.y, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::SameLine();
	if (ImGui::DragFloat("Z##scale", &scale.z, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::PopItemWidth();

	if (has_been_modified)
	{
		transform_matrix = transform_matrix.FromEulerXYZ(rotation_euler_angles.x * DEGTORAD, rotation_euler_angles.y  * DEGTORAD, rotation_euler_angles.z  * DEGTORAD);
		transform_matrix = transform_matrix * transform_matrix.Scale(scale, math::float3(0, 0, 0));
		transform_matrix.SetTranslatePart(position.x, position.y, position.z);
	}
}
<commit_msg>Moved transformation to update<commit_after>#include "ComponentTransform.h"

// Constructors =================================
ComponentTransform::ComponentTransform() : Component(COMP_TRANSFORMATION)
{
	transform_matrix = math::float4x4::identity;
	position = { 0,0,0 };
	rotation_euler_angles = { 0,0,0 };
	scale = { 0,0,0 };
	rotation_quaternion = math::Quat::identity;
}

ComponentTransform::ComponentTransform(const ComponentTransform & cpy) : Component(cpy), position(cpy.position), scale(cpy.scale), rotation_euler_angles(cpy.rotation_euler_angles), transform_matrix(cpy.transform_matrix)
{

}

// Destructors ==================================
ComponentTransform::~ComponentTransform()
{

}

bool ComponentTransform::Update()
{
	if (has_been_modified)
	{
		UpdateTransform();
	}

	return true;
}

// Set Methods ==================================
void ComponentTransform::SetTransformation(aiMatrix4x4 trans)
{
	//Set the mathgeolib matrix from assim matrix
	float values[16] =
	{
		trans.a1, trans.a2, trans.a3, trans.a4,
		trans.b1, trans.b2, trans.b3, trans.b4,
		trans.c1, trans.c2, trans.c3, trans.c4,
		trans.d1, trans.d2, trans.d3, trans.d4
	};

	transform_matrix.Set(values);

	//Set the variables that will be shown in the UI
	transform_matrix.Decompose(position, rotation_quaternion, scale);
	rotation_euler_angles = (rotation_quaternion.ToEulerXYZ() * RADTODEG);
}

void ComponentTransform::SetTransformation(math::float4x4 trans)
{
	transform_matrix = trans;

	transform_matrix.Decompose(position, rotation_quaternion, scale);
	rotation_euler_angles = rotation_quaternion.ToEulerXYZ();
}

// Get Methods ==================================
math::float3 ComponentTransform::GetPosition() const
{
	return position;
}

math::float3 ComponentTransform::GetRotationEuler() const
{
	return rotation_euler_angles;
}

math::Quat ComponentTransform::GetRotationQuat() const
{
	return rotation_quaternion;
}

math::float3 ComponentTransform::GetScale() const
{
	return scale;
}

const float* ComponentTransform::GetTransformMatrixRows() const
{
	return transform_matrix.ptr();
}

const float* ComponentTransform::GetTransformMatrixColumns() const
{
	return transform_matrix.Transposed().ptr();
}

// Functionality ================================
void ComponentTransform::BlitComponentInspector()
{
	ImGui::Separator();

	ImGui::Checkbox("##transform_comp", &actived);
	ImGui::SameLine();
	ImGui::TextColored(ImVec4(1.0f, 0.64f, 0.0f, 1.0f), "Transform");

	//Transform Position
	ImGui::Text("Position ");
	ImGui::SameLine();
	ImGui::PushItemWidth(50);
	if (ImGui::DragFloat("X##position", &position.x, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::SameLine();
	if (ImGui::DragFloat("Y##position", &position.y, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::SameLine();
	if (ImGui::DragFloat("Z##position", &position.z, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;

	//Transform rotation
	bool has_rotate = false;
	ImGui::Text("Rotation ");
	ImGui::SameLine();
	ImGui::PushItemWidth(50);
	if (ImGui::DragFloat("X##rotation", &rotation_euler_angles.x, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::SameLine();
	if (ImGui::DragFloat("Y##rotation", &rotation_euler_angles.y, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::SameLine();
	if (ImGui::DragFloat("Z##rotation", &rotation_euler_angles.z, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;

	//Transform rotation
	bool has_scale = false;
	ImGui::Text("Scale    ");
	ImGui::SameLine();
	if (ImGui::DragFloat("X##scale", &scale.x, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::SameLine();
	if (ImGui::DragFloat("Y##scale", &scale.y, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::SameLine();
	if (ImGui::DragFloat("Z##scale", &scale.z, 0.5f, 0.0f, 0.0f, "%.2f")) has_been_modified = true;
	ImGui::PopItemWidth();

}

void ComponentTransform::UpdateTransform()
{
	rotation_quaternion = math::Quat::FromEulerXYZ(rotation_euler_angles.x * DEGTORAD, rotation_euler_angles.y  * DEGTORAD, rotation_euler_angles.z  * DEGTORAD);

	transform_matrix = math::float4x4::FromQuat(rotation_quaternion);
	transform_matrix = math::float4x4::Scale(scale, math::float3(0, 0, 0)) * transform_matrix;
	transform_matrix.SetTranslatePart(position.x, position.y, position.z);
	has_been_modified = false;
}
<|endoftext|>


<commit_before>#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkImageRegionIterator.h"
#include "itkRGBPixel.h"
#include "itkRGBAPixel.h"

#include "itkRedColormapFunctor.h"
#include "itkGreenColormapFunctor.h"
#include "itkBlueColormapFunctor.h"
#include "itkGreyColormapFunctor.h"
#include "itkHotColormapFunctor.h"
#include "itkCoolColormapFunctor.h"
#include "itkSpringColormapFunctor.h"
#include "itkSummerColormapFunctor.h"
#include "itkAutumnColormapFunctor.h"
#include "itkWinterColormapFunctor.h"
#include "itkCopperColormapFunctor.h"
#include "itkHSVColormapFunctor.h"
#include "itkJetColormapFunctor.h"
#include "itkCustomColormapFunctor.h"
#include "itkOverUnderColormapFunctor.h"

#include "itkScalarToRGBColormapImageFilter.h"

#include <fstream.h>
#include <sstream>
#include <string>

template <unsigned int ImageDimension>
int ConvertScalarImageToRGB( int argc, char *argv[] )
{
  typedef unsigned int PixelType;
//  typedef itk::RGBPixel<unsigned char> RGBPixelType;
  typedef itk::RGBAPixel<unsigned char> RGBPixelType;

  typedef float RealType;

  typedef itk::Image<PixelType, ImageDimension>    ImageType;
  typedef itk::Image<float, ImageDimension>        RealImageType;
  typedef itk::Image<RGBPixelType, ImageDimension> RGBImageType;

  typedef itk::ImageFileReader<RealImageType> ReaderType;
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[2] );
  reader->Update();

  typedef itk::Image<unsigned char, ImageDimension> MaskImageType;
  typename MaskImageType::Pointer maskImage = MaskImageType::New();
  typedef itk::ImageFileReader<MaskImageType> MaskReaderType;
  typename MaskReaderType::Pointer maskreader = MaskReaderType::New();
  maskreader->SetFileName( argv[4] );
  try
    {
    maskreader->Update();
    maskImage = maskreader->GetOutput();
    }
  catch( ... )
    {
    maskImage = NULL;
    }
  ;

  std::string colormapString( argv[5] );

  typedef itk::ScalarToRGBColormapImageFilter<RealImageType,
                                              RGBImageType> RGBFilterType;
  typename RGBFilterType::Pointer rgbfilter = RGBFilterType::New();
  rgbfilter->SetInput( reader->GetOutput() );

  if( colormapString == "red" )
    {
    rgbfilter->SetColormap( RGBFilterType::Red );
    }
  else if( colormapString == "green"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Green );
    }
  else if( colormapString == "blue"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Blue );
    }
  else if( colormapString == "grey"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Grey );
    }
  else if( colormapString == "cool"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Cool );
    }
  else if( colormapString == "hot"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Hot );
    }
  else if( colormapString == "spring"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Spring );
    }
  else if( colormapString == "autumn"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Autumn );
    }
  else if( colormapString == "winter"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Winter );
    }
  else if( colormapString == "copper"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Copper );
    }
  else if( colormapString == "summer"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Summer );
    }
  else if( colormapString == "jet"  )
    {
//    rgbfilter->SetColormap( RGBFilterType::Jet );
    typedef itk::Functor::JetColormapFunctor<typename RealImageType::PixelType,
                                             typename RGBImageType::PixelType> ColormapType;
    typename ColormapType::Pointer colormap = ColormapType::New();
    rgbfilter->SetColormap( colormap );
    }
  else if( colormapString == "hsv"  )
    {
//    rgbfilter->SetColormap( RGBFilterType::HSV );
    typedef itk::Functor::HSVColormapFunctor<typename RealImageType::PixelType,
                                             typename RGBImageType::PixelType> ColormapType;
    typename ColormapType::Pointer colormap = ColormapType::New();
    rgbfilter->SetColormap( colormap );
    }
  else if( colormapString == "overunder"  )
    {
    rgbfilter->SetColormap( RGBFilterType::OverUnder );
    }
  else if( colormapString == "custom"  )
    {
    typedef itk::Functor::CustomColormapFunctor<typename RealImageType::PixelType,
                                                typename RGBImageType::PixelType> ColormapType;
    typename ColormapType::Pointer colormap = ColormapType::New();

    ifstream    str( argv[6] );
    std::string line;

    // Get red values
      {
      std::getline( str, line );
      std::istringstream iss( line );
      float              value;
      typename ColormapType::ChannelType channel;
      while( iss >> value )
        {
        channel.push_back( value );
        }

      colormap->SetRedChannel( channel );
      }

    // Get green values
      {
      std::getline( str, line );
      std::istringstream iss( line );
      float              value;
      typename ColormapType::ChannelType channel;
      while( iss >> value )
        {
        channel.push_back( value );
        }

      colormap->SetGreenChannel( channel );
      }
    // Get blue values
      {
      std::getline( str, line );
      std::istringstream iss( line );
      float              value;
      typename ColormapType::ChannelType channel;
      while( iss >> value )
        {
        channel.push_back( value );
        }

      colormap->SetBlueChannel( channel );
      }
    rgbfilter->SetColormap( colormap );
    }

  if( maskImage )
    {
    RealType maskMinimumValue = itk::NumericTraits<RealType>::max();
    RealType maskMaximumValue = itk::NumericTraits<RealType>::NonpositiveMin();

    itk::ImageRegionIterator<MaskImageType> ItM( maskImage,
                                                 maskImage->GetLargestPossibleRegion() );
    itk::ImageRegionIterator<RealImageType> ItS( reader->GetOutput(),
                                                 reader->GetOutput()->GetLargestPossibleRegion() );
    for( ItM.GoToBegin(), ItS.GoToBegin(); !ItM.IsAtEnd(); ++ItM, ++ItS )
      {
      if( ItM.Get() != 0 )
        {
        if( maskMinimumValue >= ItS.Get() )
          {
          maskMinimumValue = ItS.Get();
          }
        if( maskMaximumValue <= ItS.Get() )
          {
          maskMaximumValue = ItS.Get();
          }
        }
      }

    rgbfilter->SetUseInputImageExtremaForScaling( false );
    rgbfilter->GetColormap()->SetMinimumInputValue( maskMinimumValue );
    rgbfilter->GetColormap()->SetMaximumInputValue( maskMaximumValue );
    }

  rgbfilter->GetColormap()->SetMinimumRGBComponentValue(
    ( argc > 9 ) ? static_cast<
      typename RGBPixelType::ComponentType>( atof( argv[9] ) ) : 0 );
  rgbfilter->GetColormap()->SetMaximumRGBComponentValue(
    ( argc > 10 ) ? static_cast<
      typename RGBPixelType::ComponentType>( atof( argv[10] ) ) : 255 );

  if( argc > 8 )
    {
    rgbfilter->SetUseInputImageExtremaForScaling( false );
    rgbfilter->GetColormap()->SetMinimumInputValue(
      static_cast<RealType>( atof( argv[7] ) ) );
    rgbfilter->GetColormap()->SetMaximumInputValue(
      static_cast<RealType>( atof( argv[8] ) ) );
    }

  try
    {
    rgbfilter->Update();
    }
  catch( ... )
    {
    return EXIT_FAILURE;
    }

  if( maskImage )
    {
    itk::ImageRegionIterator<MaskImageType> ItM( maskImage,
                                                 maskImage->GetLargestPossibleRegion() );
    itk::ImageRegionIterator<RGBImageType> ItC( rgbfilter->GetOutput(),
                                                rgbfilter->GetOutput()->GetLargestPossibleRegion() );
    itk::ImageRegionIterator<RealImageType> ItS( reader->GetOutput(),
                                                 reader->GetOutput()->GetLargestPossibleRegion() );

    ItM.GoToBegin();
    ItC.GoToBegin();
    ItS.GoToBegin();

    while( !ItM.IsAtEnd() )
      {
      if( ItM.Get() == 0 )
        {
        RGBPixelType rgbpixel;

//        RealType minimumValue = rgbfilter->GetColormap()->GetMinimumInputValue();
//        RealType maximumValue = rgbfilter->GetColormap()->GetMaximumInputValue();
//
//        RealType minimumRGBValue
//          = rgbfilter->GetColormap()->GetMinimumRGBComponentValue();
//        RealType maximumRGBValue
//          = rgbfilter->GetColormap()->GetMaximumRGBComponentValue();
//
//        RealType ratio = ( ItS.Get() - minimumValue ) / ( maximumValue - minimumValue );
//
//        rgbpixel.Fill( ratio * ( maximumRGBValue - minimumRGBValue )
//          + minimumRGBValue );
        rgbpixel.Fill( 0.0 );

        ItC.Set( rgbpixel );
        }
      ++ItM;
      ++ItC;
      ++ItS;
      }
    }

  std::cout << rgbfilter->GetColormap()->GetMinimumInputValue() << ", "
            << rgbfilter->GetColormap()->GetMaximumInputValue() << std::endl;

  typedef itk::ImageFileWriter<RGBImageType> WriterType;
  typename WriterType::Pointer writer = WriterType::New();
  writer->SetInput( rgbfilter->GetOutput() );
  writer->SetFileName( argv[3] );
  writer->Update();

  return 0;
}

int main( int argc, char *argv[] )
{
  if( argc < 6 )
    {
    std::cout << "Usage: " << argv[0] << " imageDimension inputImage outputImage "
              << "mask colormap [customColormapFile] [minimumInput] [maximumInput] "
              << "[minimumRGBOutput] [maximumRGBOutput]" << std::endl;
    std::cout << "  Possible colormaps: grey, red, green, blue, copper, jet, hsv, ";
    std::cout << "spring, summer, autumn, winter, hot, cool, overunder, custom" << std::endl;
    exit( 1 );
    }

  switch( atoi( argv[1] ) )
    {
    case 2:
      ConvertScalarImageToRGB<2>( argc, argv );
      break;
    case 3:
      ConvertScalarImageToRGB<3>( argc, argv );
      break;
    default:
      std::cerr << "Unsupported dimension" << std::endl;
      exit( EXIT_FAILURE );
    }
}
<commit_msg>removed debugging print statement.<commit_after>#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkImageRegionIterator.h"
#include "itkRGBPixel.h"
#include "itkRGBAPixel.h"

#include "itkRedColormapFunctor.h"
#include "itkGreenColormapFunctor.h"
#include "itkBlueColormapFunctor.h"
#include "itkGreyColormapFunctor.h"
#include "itkHotColormapFunctor.h"
#include "itkCoolColormapFunctor.h"
#include "itkSpringColormapFunctor.h"
#include "itkSummerColormapFunctor.h"
#include "itkAutumnColormapFunctor.h"
#include "itkWinterColormapFunctor.h"
#include "itkCopperColormapFunctor.h"
#include "itkHSVColormapFunctor.h"
#include "itkJetColormapFunctor.h"
#include "itkCustomColormapFunctor.h"
#include "itkOverUnderColormapFunctor.h"

#include "itkScalarToRGBColormapImageFilter.h"

#include <fstream.h>
#include <sstream>
#include <string>

template <unsigned int ImageDimension>
int ConvertScalarImageToRGB( int argc, char *argv[] )
{
  typedef unsigned int PixelType;
//  typedef itk::RGBPixel<unsigned char> RGBPixelType;
  typedef itk::RGBAPixel<unsigned char> RGBPixelType;

  typedef float RealType;

  typedef itk::Image<PixelType, ImageDimension>    ImageType;
  typedef itk::Image<float, ImageDimension>        RealImageType;
  typedef itk::Image<RGBPixelType, ImageDimension> RGBImageType;

  typedef itk::ImageFileReader<RealImageType> ReaderType;
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[2] );
  reader->Update();

  typedef itk::Image<unsigned char, ImageDimension> MaskImageType;
  typename MaskImageType::Pointer maskImage = MaskImageType::New();
  typedef itk::ImageFileReader<MaskImageType> MaskReaderType;
  typename MaskReaderType::Pointer maskreader = MaskReaderType::New();
  maskreader->SetFileName( argv[4] );
  try
    {
    maskreader->Update();
    maskImage = maskreader->GetOutput();
    }
  catch( ... )
    {
    maskImage = NULL;
    }
  ;

  std::string colormapString( argv[5] );

  typedef itk::ScalarToRGBColormapImageFilter<RealImageType,
                                              RGBImageType> RGBFilterType;
  typename RGBFilterType::Pointer rgbfilter = RGBFilterType::New();
  rgbfilter->SetInput( reader->GetOutput() );

  if( colormapString == "red" )
    {
    rgbfilter->SetColormap( RGBFilterType::Red );
    }
  else if( colormapString == "green"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Green );
    }
  else if( colormapString == "blue"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Blue );
    }
  else if( colormapString == "grey"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Grey );
    }
  else if( colormapString == "cool"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Cool );
    }
  else if( colormapString == "hot"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Hot );
    }
  else if( colormapString == "spring"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Spring );
    }
  else if( colormapString == "autumn"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Autumn );
    }
  else if( colormapString == "winter"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Winter );
    }
  else if( colormapString == "copper"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Copper );
    }
  else if( colormapString == "summer"  )
    {
    rgbfilter->SetColormap( RGBFilterType::Summer );
    }
  else if( colormapString == "jet"  )
    {
//    rgbfilter->SetColormap( RGBFilterType::Jet );
    typedef itk::Functor::JetColormapFunctor<typename RealImageType::PixelType,
                                             typename RGBImageType::PixelType> ColormapType;
    typename ColormapType::Pointer colormap = ColormapType::New();
    rgbfilter->SetColormap( colormap );
    }
  else if( colormapString == "hsv"  )
    {
//    rgbfilter->SetColormap( RGBFilterType::HSV );
    typedef itk::Functor::HSVColormapFunctor<typename RealImageType::PixelType,
                                             typename RGBImageType::PixelType> ColormapType;
    typename ColormapType::Pointer colormap = ColormapType::New();
    rgbfilter->SetColormap( colormap );
    }
  else if( colormapString == "overunder"  )
    {
    rgbfilter->SetColormap( RGBFilterType::OverUnder );
    }
  else if( colormapString == "custom"  )
    {
    typedef itk::Functor::CustomColormapFunctor<typename RealImageType::PixelType,
                                                typename RGBImageType::PixelType> ColormapType;
    typename ColormapType::Pointer colormap = ColormapType::New();

    ifstream    str( argv[6] );
    std::string line;

    // Get red values
      {
      std::getline( str, line );
      std::istringstream iss( line );
      float              value;
      typename ColormapType::ChannelType channel;
      while( iss >> value )
        {
        channel.push_back( value );
        }

      colormap->SetRedChannel( channel );
      }

    // Get green values
      {
      std::getline( str, line );
      std::istringstream iss( line );
      float              value;
      typename ColormapType::ChannelType channel;
      while( iss >> value )
        {
        channel.push_back( value );
        }

      colormap->SetGreenChannel( channel );
      }
    // Get blue values
      {
      std::getline( str, line );
      std::istringstream iss( line );
      float              value;
      typename ColormapType::ChannelType channel;
      while( iss >> value )
        {
        channel.push_back( value );
        }

      colormap->SetBlueChannel( channel );
      }
    rgbfilter->SetColormap( colormap );
    }

  if( maskImage )
    {
    RealType maskMinimumValue = itk::NumericTraits<RealType>::max();
    RealType maskMaximumValue = itk::NumericTraits<RealType>::NonpositiveMin();

    itk::ImageRegionIterator<MaskImageType> ItM( maskImage,
                                                 maskImage->GetLargestPossibleRegion() );
    itk::ImageRegionIterator<RealImageType> ItS( reader->GetOutput(),
                                                 reader->GetOutput()->GetLargestPossibleRegion() );
    for( ItM.GoToBegin(), ItS.GoToBegin(); !ItM.IsAtEnd(); ++ItM, ++ItS )
      {
      if( ItM.Get() != 0 )
        {
        if( maskMinimumValue >= ItS.Get() )
          {
          maskMinimumValue = ItS.Get();
          }
        if( maskMaximumValue <= ItS.Get() )
          {
          maskMaximumValue = ItS.Get();
          }
        }
      }

    rgbfilter->SetUseInputImageExtremaForScaling( false );
    rgbfilter->GetColormap()->SetMinimumInputValue( maskMinimumValue );
    rgbfilter->GetColormap()->SetMaximumInputValue( maskMaximumValue );
    }

  rgbfilter->GetColormap()->SetMinimumRGBComponentValue(
    ( argc > 9 ) ? static_cast<
      typename RGBPixelType::ComponentType>( atof( argv[9] ) ) : 0 );
  rgbfilter->GetColormap()->SetMaximumRGBComponentValue(
    ( argc > 10 ) ? static_cast<
      typename RGBPixelType::ComponentType>( atof( argv[10] ) ) : 255 );

  if( argc > 8 )
    {
    rgbfilter->SetUseInputImageExtremaForScaling( false );
    rgbfilter->GetColormap()->SetMinimumInputValue(
      static_cast<RealType>( atof( argv[7] ) ) );
    rgbfilter->GetColormap()->SetMaximumInputValue(
      static_cast<RealType>( atof( argv[8] ) ) );
    }

  try
    {
    rgbfilter->Update();
    }
  catch( ... )
    {
    return EXIT_FAILURE;
    }

  if( maskImage )
    {
    itk::ImageRegionIterator<MaskImageType> ItM( maskImage,
                                                 maskImage->GetLargestPossibleRegion() );
    itk::ImageRegionIterator<RGBImageType> ItC( rgbfilter->GetOutput(),
                                                rgbfilter->GetOutput()->GetLargestPossibleRegion() );
    itk::ImageRegionIterator<RealImageType> ItS( reader->GetOutput(),
                                                 reader->GetOutput()->GetLargestPossibleRegion() );

    ItM.GoToBegin();
    ItC.GoToBegin();
    ItS.GoToBegin();

    while( !ItM.IsAtEnd() )
      {
      if( ItM.Get() == 0 )
        {
        RGBPixelType rgbpixel;

//        RealType minimumValue = rgbfilter->GetColormap()->GetMinimumInputValue();
//        RealType maximumValue = rgbfilter->GetColormap()->GetMaximumInputValue();
//
//        RealType minimumRGBValue
//          = rgbfilter->GetColormap()->GetMinimumRGBComponentValue();
//        RealType maximumRGBValue
//          = rgbfilter->GetColormap()->GetMaximumRGBComponentValue();
//
//        RealType ratio = ( ItS.Get() - minimumValue ) / ( maximumValue - minimumValue );
//
//        rgbpixel.Fill( ratio * ( maximumRGBValue - minimumRGBValue )
//          + minimumRGBValue );
        rgbpixel.Fill( 0.0 );

        ItC.Set( rgbpixel );
        }
      ++ItM;
      ++ItC;
      ++ItS;
      }
    }

  typedef itk::ImageFileWriter<RGBImageType> WriterType;
  typename WriterType::Pointer writer = WriterType::New();
  writer->SetInput( rgbfilter->GetOutput() );
  writer->SetFileName( argv[3] );
  writer->Update();

  return 0;
}

int main( int argc, char *argv[] )
{
  if( argc < 6 )
    {
    std::cout << "Usage: " << argv[0] << " imageDimension inputImage outputImage "
              << "mask colormap [customColormapFile] [minimumInput] [maximumInput] "
              << "[minimumRGBOutput] [maximumRGBOutput]" << std::endl;
    std::cout << "  Possible colormaps: grey, red, green, blue, copper, jet, hsv, ";
    std::cout << "spring, summer, autumn, winter, hot, cool, overunder, custom" << std::endl;
    exit( 1 );
    }

  switch( atoi( argv[1] ) )
    {
    case 2:
      ConvertScalarImageToRGB<2>( argc, argv );
      break;
    case 3:
      ConvertScalarImageToRGB<3>( argc, argv );
      break;
    default:
      std::cerr << "Unsupported dimension" << std::endl;
      exit( EXIT_FAILURE );
    }
}
<|endoftext|>


<commit_before><commit_msg>Delete Puentes itmos.cpp<commit_after><|endoftext|>


<commit_before><commit_msg>Avoid nullptr dereferences in sycc444_to_rgb().<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/logging.h"
#include "media/base/callback.h"
#include "media/base/media.h"
#include "remoting/base/capture_data.h"
#include "remoting/base/encoder_vp8.h"
#include "remoting/proto/video.pb.h"

extern "C" {
#define VPX_CODEC_DISABLE_COMPAT 1
#include "third_party/libvpx/include/vpx/vpx_codec.h"
#include "third_party/libvpx/include/vpx/vpx_encoder.h"
#include "third_party/libvpx/include/vpx/vp8cx.h"
}

namespace remoting {

EncoderVp8::EncoderVp8()
    : initialized_(false),
      codec_(NULL),
      image_(NULL),
      last_timestamp_(0) {
}

EncoderVp8::~EncoderVp8() {
  if (initialized_) {
    vpx_codec_err_t ret = vpx_codec_destroy(codec_.get());
    DCHECK(ret == VPX_CODEC_OK) << "Failed to destroy codec";
  }
}

bool EncoderVp8::Init(int width, int height) {
  codec_.reset(new vpx_codec_ctx_t());
  image_.reset(new vpx_image_t());
  memset(image_.get(), 0, sizeof(vpx_image_t));

  image_->fmt = VPX_IMG_FMT_YV12;

  // libvpx seems to require both to be assigned.
  image_->d_w = width;
  image_->w = width;
  image_->d_h = height;
  image_->h = height;

  vpx_codec_enc_cfg_t config;
  const vpx_codec_iface_t* algo =
      (const vpx_codec_iface_t*)media::GetVp8CxAlgoAddress();
  CHECK(algo);
  vpx_codec_err_t ret = vpx_codec_enc_config_default(algo, &config, 0);
  if (ret != VPX_CODEC_OK)
    return false;

  // TODO(hclam): Tune the parameters to better suit the application.
  config.rc_target_bitrate = width * height * config.rc_target_bitrate
      / config.g_w / config.g_h;
  config.g_w = width;
  config.g_h = height;
  config.g_pass = VPX_RC_ONE_PASS;
  config.g_profile = 1;
  config.g_threads = 2;
  config.rc_min_quantizer = 0;
  config.rc_max_quantizer = 15;
  config.g_timebase.num = 1;
  config.g_timebase.den = 30;

  if (vpx_codec_enc_init(codec_.get(), algo, &config, 0))
    return false;
  return true;
}

static int clip_byte(int x) {
  if (x > 255)
    return 255;
  else if (x < 0)
    return 0;
  else
    return x;
}

bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data) {
  const int plane_size = capture_data->width() * capture_data->height();

  if (!yuv_image_.get()) {

    // YUV image size is 1.5 times of a plane. Multiplication is performed first
    // to avoid rounding error.
    const int size = plane_size * 3 / 2;

    yuv_image_.reset(new uint8[size]);

    // Reset image value to 128 so we just need to fill in the y plane.
    memset(yuv_image_.get(), 128, size);

    // Fill in the information for |image_|.
    unsigned char* image = reinterpret_cast<unsigned char*>(yuv_image_.get());
    image_->planes[0] = image;
    image_->planes[1] = image + plane_size;

    // The V plane starts from 1.25 of the plane size.
    image_->planes[2] = image + plane_size + plane_size / 4;

    // In YV12 Y plane has full width, UV plane has half width because of
    // subsampling.
    image_->stride[0] = image_->w;
    image_->stride[1] = image_->w / 2;
    image_->stride[2] = image_->w / 2;
  }

  // And then do RGB->YUV conversion.
  // Currently we just produce the Y channel as the average of RGB. This will
  // giv ae gray scale image after conversion.
  // TODO(sergeyu): Move this code to a separate routine.
  // TODO(sergeyu): Optimize this code.
  DCHECK(capture_data->pixel_format() == media::VideoFrame::RGB32)
      << "Only RGB32 is supported";
  uint8* in = capture_data->data_planes().data[0];
  const int in_stride = capture_data->data_planes().strides[0];
  uint8* y_out = yuv_image_.get();
  uint8* u_out = yuv_image_.get() + plane_size;
  uint8* v_out = yuv_image_.get() + plane_size + plane_size / 4;
  const int out_stride = image_->stride[0];
  for (int i = 0; i < capture_data->height(); ++i) {
    for (int j = 0; j < capture_data->width(); ++j) {
      // Since the input pixel format is RGB32, there are 4 bytes per pixel.
      uint8* pixel = in + 4 * j;
      y_out[j] = clip_byte(((pixel[0] * 66 + pixel[1] * 129 +
                             pixel[2] * 25 + 128) >> 8) + 16);
      if (i % 2 == 0 && j % 2 == 0) {
        u_out[j / 2] = clip_byte(((pixel[0] * -38 + pixel[1] * -74 +
                                   pixel[2] * 112 + 128) >> 8) + 128);
        v_out[j / 2] = clip_byte(((pixel[0] * 112 + pixel[1] * -94 +
                                   pixel[2] * -18 + 128) >> 8) + 128);
      }
    }
    in += in_stride;
    y_out += out_stride;
    if (i % 2 == 0) {
      u_out += out_stride / 2;
      v_out += out_stride / 2;
    }
  }
  return true;
}

void EncoderVp8::Encode(scoped_refptr<CaptureData> capture_data,
                        bool key_frame,
                        DataAvailableCallback* data_available_callback) {
  if (!initialized_) {
    bool ret = Init(capture_data->width(), capture_data->height());
    // TODO(hclam): Handle error better.
    DCHECK(ret) << "Initialization of encoder failed";
    initialized_ = ret;
  }

  if (!PrepareImage(capture_data)) {
    NOTREACHED() << "Can't image data for encoding";
  }

  // Do the actual encoding.
  vpx_codec_err_t ret = vpx_codec_encode(codec_.get(), image_.get(),
                                         last_timestamp_,
                                         1, 0, VPX_DL_REALTIME);
  DCHECK_EQ(ret, VPX_CODEC_OK)
      << "Encoding error: " << vpx_codec_err_to_string(ret) << "\n"
      << "Details: " << vpx_codec_error(codec_.get()) << "\n"
      << vpx_codec_error_detail(codec_.get());

  // TODO(hclam): fix this.
  last_timestamp_ += 100;

  // Read the encoded data.
  vpx_codec_iter_t iter = NULL;
  bool got_data = false;

  // TODO(hclam): Make sure we get exactly one frame from the packet.
  // TODO(hclam): We should provide the output buffer to avoid one copy.
  VideoPacket* message = new VideoPacket();

  while (!got_data) {
    const vpx_codec_cx_pkt_t* packet = vpx_codec_get_cx_data(codec_.get(),
                                                             &iter);
    if (!packet)
      continue;

    switch (packet->kind) {
      case VPX_CODEC_CX_FRAME_PKT:
        got_data = true;
        message->set_data(packet->data.frame.buf, packet->data.frame.sz);
        break;
      default:
        break;
    }
  }

  message->mutable_format()->set_encoding(VideoPacketFormat::ENCODING_VP8);
  message->set_flags(VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET);

  data_available_callback->Run(message);
  delete data_available_callback;
}

}  // namespace remoting
<commit_msg>Refactor ZLib and Verbatim encoders.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/logging.h"
#include "media/base/callback.h"
#include "media/base/media.h"
#include "remoting/base/capture_data.h"
#include "remoting/base/encoder_vp8.h"
#include "remoting/proto/video.pb.h"

extern "C" {
#define VPX_CODEC_DISABLE_COMPAT 1
#include "third_party/libvpx/include/vpx/vpx_codec.h"
#include "third_party/libvpx/include/vpx/vpx_encoder.h"
#include "third_party/libvpx/include/vpx/vp8cx.h"
}

namespace remoting {

EncoderVp8::EncoderVp8()
    : initialized_(false),
      codec_(NULL),
      image_(NULL),
      last_timestamp_(0) {
}

EncoderVp8::~EncoderVp8() {
  if (initialized_) {
    vpx_codec_err_t ret = vpx_codec_destroy(codec_.get());
    DCHECK(ret == VPX_CODEC_OK) << "Failed to destroy codec";
  }
}

bool EncoderVp8::Init(int width, int height) {
  codec_.reset(new vpx_codec_ctx_t());
  image_.reset(new vpx_image_t());
  memset(image_.get(), 0, sizeof(vpx_image_t));

  image_->fmt = VPX_IMG_FMT_YV12;

  // libvpx seems to require both to be assigned.
  image_->d_w = width;
  image_->w = width;
  image_->d_h = height;
  image_->h = height;

  vpx_codec_enc_cfg_t config;
  const vpx_codec_iface_t* algo =
      (const vpx_codec_iface_t*)media::GetVp8CxAlgoAddress();
  CHECK(algo);
  vpx_codec_err_t ret = vpx_codec_enc_config_default(algo, &config, 0);
  if (ret != VPX_CODEC_OK)
    return false;

  // TODO(hclam): Tune the parameters to better suit the application.
  config.rc_target_bitrate = width * height * config.rc_target_bitrate
      / config.g_w / config.g_h;
  config.g_w = width;
  config.g_h = height;
  config.g_pass = VPX_RC_ONE_PASS;
  config.g_profile = 1;
  config.g_threads = 2;
  config.rc_min_quantizer = 0;
  config.rc_max_quantizer = 15;
  config.g_timebase.num = 1;
  config.g_timebase.den = 30;

  if (vpx_codec_enc_init(codec_.get(), algo, &config, 0))
    return false;
  return true;
}

static int clip_byte(int x) {
  if (x > 255)
    return 255;
  else if (x < 0)
    return 0;
  else
    return x;
}

bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data) {
  const int plane_size = capture_data->width() * capture_data->height();

  if (!yuv_image_.get()) {

    // YUV image size is 1.5 times of a plane. Multiplication is performed first
    // to avoid rounding error.
    const int size = plane_size * 3 / 2;

    yuv_image_.reset(new uint8[size]);

    // Reset image value to 128 so we just need to fill in the y plane.
    memset(yuv_image_.get(), 128, size);

    // Fill in the information for |image_|.
    unsigned char* image = reinterpret_cast<unsigned char*>(yuv_image_.get());
    image_->planes[0] = image;
    image_->planes[1] = image + plane_size;

    // The V plane starts from 1.25 of the plane size.
    image_->planes[2] = image + plane_size + plane_size / 4;

    // In YV12 Y plane has full width, UV plane has half width because of
    // subsampling.
    image_->stride[0] = image_->w;
    image_->stride[1] = image_->w / 2;
    image_->stride[2] = image_->w / 2;
  }

  // And then do RGB->YUV conversion.
  // Currently we just produce the Y channel as the average of RGB. This will
  // giv ae gray scale image after conversion.
  // TODO(sergeyu): Move this code to a separate routine.
  // TODO(sergeyu): Optimize this code.
  DCHECK(capture_data->pixel_format() == media::VideoFrame::RGB32)
      << "Only RGB32 is supported";
  uint8* in = capture_data->data_planes().data[0];
  const int in_stride = capture_data->data_planes().strides[0];
  uint8* y_out = yuv_image_.get();
  uint8* u_out = yuv_image_.get() + plane_size;
  uint8* v_out = yuv_image_.get() + plane_size + plane_size / 4;
  const int out_stride = image_->stride[0];
  for (int i = 0; i < capture_data->height(); ++i) {
    for (int j = 0; j < capture_data->width(); ++j) {
      // Since the input pixel format is RGB32, there are 4 bytes per pixel.
      uint8* pixel = in + 4 * j;
      y_out[j] = clip_byte(((pixel[2] * 66 + pixel[1] * 129 +
                             pixel[0] * 25 + 128) >> 8) + 16);
      if (i % 2 == 0 && j % 2 == 0) {
        u_out[j / 2] = clip_byte(((pixel[2] * -38 + pixel[1] * -74 +
                                   pixel[0] * 112 + 128) >> 8) + 128);
        v_out[j / 2] = clip_byte(((pixel[2] * 112 + pixel[1] * -94 +
                                   pixel[1] * -18 + 128) >> 8) + 128);
      }
    }
    in += in_stride;
    y_out += out_stride;
    if (i % 2 == 0) {
      u_out += out_stride / 2;
      v_out += out_stride / 2;
    }
  }
  return true;
}

void EncoderVp8::Encode(scoped_refptr<CaptureData> capture_data,
                        bool key_frame,
                        DataAvailableCallback* data_available_callback) {
  if (!initialized_) {
    bool ret = Init(capture_data->width(), capture_data->height());
    // TODO(hclam): Handle error better.
    DCHECK(ret) << "Initialization of encoder failed";
    initialized_ = ret;
  }

  if (!PrepareImage(capture_data)) {
    NOTREACHED() << "Can't image data for encoding";
  }

  // Do the actual encoding.
  vpx_codec_err_t ret = vpx_codec_encode(codec_.get(), image_.get(),
                                         last_timestamp_,
                                         1, 0, VPX_DL_REALTIME);
  DCHECK_EQ(ret, VPX_CODEC_OK)
      << "Encoding error: " << vpx_codec_err_to_string(ret) << "\n"
      << "Details: " << vpx_codec_error(codec_.get()) << "\n"
      << vpx_codec_error_detail(codec_.get());

  // TODO(hclam): fix this.
  last_timestamp_ += 100;

  // Read the encoded data.
  vpx_codec_iter_t iter = NULL;
  bool got_data = false;

  // TODO(hclam): Make sure we get exactly one frame from the packet.
  // TODO(hclam): We should provide the output buffer to avoid one copy.
  VideoPacket* message = new VideoPacket();

  while (!got_data) {
    const vpx_codec_cx_pkt_t* packet = vpx_codec_get_cx_data(codec_.get(),
                                                             &iter);
    if (!packet)
      continue;

    switch (packet->kind) {
      case VPX_CODEC_CX_FRAME_PKT:
        got_data = true;
        message->set_data(packet->data.frame.buf, packet->data.frame.sz);
        break;
      default:
        break;
    }
  }

  message->mutable_format()->set_encoding(VideoPacketFormat::ENCODING_VP8);
  message->set_flags(VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET);

  data_available_callback->Run(message);
  delete data_available_callback;
}

}  // namespace remoting
<|endoftext|>


<commit_before>#include <muduo/base/Logging.h>
#include <muduo/net/Channel.h>
#include <muduo/net/EventLoop.h>

#include <map>

#include <boost/bind.hpp>

#include <stdio.h>
#include <unistd.h>
#include <sys/timerfd.h>

using namespace muduo;
using namespace muduo::net;

void print(const char* msg)
{
  static std::map<const char*, Timestamp> lasts;
  Timestamp& last = lasts[msg];
  Timestamp now = Timestamp::now();
  printf("%s tid %d %s delay %f\n", now.toString().c_str(), CurrentThread::tid(),
         msg, timeDifference(now, last));
  last = now;
}

namespace muduo
{
namespace net
{
namespace detail
{
int createTimerfd();
void readTimerfd(int timerfd, Timestamp now);
}
}
}

// Use relative time, immunized to wall clock changes.
class PeriodicTimer
{
 public:
  PeriodicTimer(EventLoop* loop, double interval, const TimerCallback& cb)
    : loop_(loop),
      timerfd_(muduo::net::detail::createTimerfd()),
      timerfdChannel_(loop, timerfd_),
      interval_(interval),
      cb_(cb)
  {
    timerfdChannel_.setReadCallback(
        boost::bind(&PeriodicTimer::handleRead, this));
    timerfdChannel_.enableReading();
  }

  void start()
  {
    struct itimerspec spec;
    bzero(&spec, sizeof spec);
    spec.it_interval = toTimeSpec(interval_);
    spec.it_value = spec.it_interval;
    int ret = ::timerfd_settime(timerfd_, 0 /* relative timer */, &spec, NULL);
    if (ret)
    {
      LOG_SYSERR << "timerfd_settime()";
    }
  }

  ~PeriodicTimer()
  {
    timerfdChannel_.disableAll();
    timerfdChannel_.remove();
    ::close(timerfd_);
  }

 private:
  void handleRead()
  {
    loop_->assertInLoopThread();
    muduo::net::detail::readTimerfd(timerfd_, Timestamp::now());
    if (cb_)
      cb_();
  }

  static struct timespec toTimeSpec(double seconds)
  {
    struct timespec ts;
    bzero(&ts, sizeof ts);
    const int64_t kNanoSecondsPerSecond = 1e9;
    int64_t nanoseconds = static_cast<int64_t>(seconds * kNanoSecondsPerSecond);
    if (nanoseconds < 1e5)
      nanoseconds = 1e5;
    ts.tv_sec = static_cast<time_t>(nanoseconds / kNanoSecondsPerSecond);
    ts.tv_nsec = static_cast<long>(nanoseconds % kNanoSecondsPerSecond);
    return ts;
  }

  EventLoop* loop_;
  const int timerfd_;
  Channel timerfdChannel_;
  const double interval_; // in seconds
  TimerCallback cb_;
};

int main(int argc, char* argv[])
{
  LOG_INFO << "pid = " << getpid() << ", tid = " << CurrentThread::tid()
           << " Try adjusting the wall clock, see what happens.";
  EventLoop loop;
  PeriodicTimer timer(&loop, 1, boost::bind(print, "PeriodicTimer"));
  timer.start();
  loop.runEvery(1, boost::bind(print, "EventLoop::runEvery"));
  loop.loop();
}
<commit_msg>fix warning on gcc6.<commit_after>#include <muduo/base/Logging.h>
#include <muduo/net/Channel.h>
#include <muduo/net/EventLoop.h>

#include <map>

#include <boost/bind.hpp>

#include <stdio.h>
#include <unistd.h>
#include <sys/timerfd.h>

using namespace muduo;
using namespace muduo::net;

void print(const char* msg)
{
  static std::map<const char*, Timestamp> lasts;
  Timestamp& last = lasts[msg];
  Timestamp now = Timestamp::now();
  printf("%s tid %d %s delay %f\n", now.toString().c_str(), CurrentThread::tid(),
         msg, timeDifference(now, last));
  last = now;
}

namespace muduo
{
namespace net
{
namespace detail
{
int createTimerfd();
void readTimerfd(int timerfd, Timestamp now);
}
}
}

// Use relative time, immunized to wall clock changes.
class PeriodicTimer
{
 public:
  PeriodicTimer(EventLoop* loop, double interval, const TimerCallback& cb)
    : loop_(loop),
      timerfd_(muduo::net::detail::createTimerfd()),
      timerfdChannel_(loop, timerfd_),
      interval_(interval),
      cb_(cb)
  {
    timerfdChannel_.setReadCallback(
        boost::bind(&PeriodicTimer::handleRead, this));
    timerfdChannel_.enableReading();
  }

  void start()
  {
    struct itimerspec spec;
    bzero(&spec, sizeof spec);
    spec.it_interval = toTimeSpec(interval_);
    spec.it_value = spec.it_interval;
    int ret = ::timerfd_settime(timerfd_, 0 /* relative timer */, &spec, NULL);
    if (ret)
    {
      LOG_SYSERR << "timerfd_settime()";
    }
  }

  ~PeriodicTimer()
  {
    timerfdChannel_.disableAll();
    timerfdChannel_.remove();
    ::close(timerfd_);
  }

 private:
  void handleRead()
  {
    loop_->assertInLoopThread();
    muduo::net::detail::readTimerfd(timerfd_, Timestamp::now());
    if (cb_)
      cb_();
  }

  static struct timespec toTimeSpec(double seconds)
  {
    struct timespec ts;
    bzero(&ts, sizeof ts);
    const int64_t kNanoSecondsPerSecond = 1e9;
    const int kMinInterval = 1e5;
    int64_t nanoseconds = static_cast<int64_t>(seconds * kNanoSecondsPerSecond);
    if (nanoseconds < kMinInterval)
      nanoseconds = kMinInterval;
    ts.tv_sec = static_cast<time_t>(nanoseconds / kNanoSecondsPerSecond);
    ts.tv_nsec = static_cast<long>(nanoseconds % kNanoSecondsPerSecond);
    return ts;
  }

  EventLoop* loop_;
  const int timerfd_;
  Channel timerfdChannel_;
  const double interval_; // in seconds
  TimerCallback cb_;
};

int main(int argc, char* argv[])
{
  LOG_INFO << "pid = " << getpid() << ", tid = " << CurrentThread::tid()
           << " Try adjusting the wall clock, see what happens.";
  EventLoop loop;
  PeriodicTimer timer(&loop, 1, boost::bind(print, "PeriodicTimer"));
  timer.start();
  loop.runEvery(1, boost::bind(print, "EventLoop::runEvery"));
  loop.loop();
}
<|endoftext|>


<commit_before>// -*- c-file-style: "cc-mode" -*-

#include "hemi.hpp"

extern "C" void Context_dealloc(Context* self) {
    self->context.Dispose();

    self->ob_type->tp_free((PyObject *)self);
}

extern "C" PyObject * Context_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) {
    Context *self = (Context *)subtype->tp_alloc(subtype, 0);

    if(self != NULL) {
        //HandleScope handle_scope;

        self->context = v8::Context::New();

        if(self->context.IsEmpty()) {
            Py_DECREF(self);
            return NULL;
        }
    }

    return (PyObject *)self;
}

extern "C" PyObject * Context_eval(Context *self, PyObject *args) {
    using namespace v8;

    char* _source;

    if(!PyArg_ParseTuple(args, "es", "utf-8", &_source))
        return NULL;

    HandleScope handle_scope;

    v8::Context::Scope context_scope(self->context);

    Handle<String> source = String::New(_source);

    PyMem_Free(_source);

    TryCatch trycatch;

    Handle<Script> script = Script::Compile(source);

    if(script.IsEmpty()) {
        Handle<Value> exception = trycatch.Exception();

        String::AsciiValue exception_str(exception);

        PyErr_SetString(PyExc_Exception, *exception_str);

        return NULL;
    }

    Handle<Value> result = script->Run();

    if(result.IsEmpty()) {
        Handle<Value> exception = trycatch.Exception();

        String::AsciiValue exception_str(exception);

        PyErr_SetString(PyExc_Exception, *exception_str);

        return NULL;
    }

    PyObject * py_result = wrap(self->context, Handle<v8::Object>(), result);

    return py_result;
}

extern "C" PyObject * Context_getlocals(Context *self, void *closure) {
    using namespace v8;

    v8::Context::Scope context_scope(self->context);

    HandleScope handle_scope;

    Handle<Value> object(self->context->Global());

    PyObject *wrapped = wrap(self->context, Handle<v8::Object>(), object);

    return wrapped;
}

extern "C" void Object_dealloc(Object* self) {
    v8::HandleScope handle_scope;

    self->object->DeleteHiddenValue(v8::String::New("hemi::wrapper"));

    self->object.Dispose();
    self->parent.Dispose();
    self->context.Dispose();

    self->ob_type->tp_free((PyObject *)self);
}

extern "C" PyObject * Object_getitem(Object *self, PyObject *item) {
    using namespace v8;

    if(PyUnicode_Check(item)) {
        PyObject *_item = PyUnicode_AsUTF8String(item);

        v8::Context::Scope context_scope(self->context);

        Handle<Value> result = self->object->GetRealNamedProperty(String::New(PyString_AS_STRING(_item)));

        Py_DECREF(_item);

        if(!result.IsEmpty())
            return wrap(self->context, self->object, result);
    }

    PyErr_SetObject(PyExc_KeyError, item);

    return NULL;
};

extern "C" PyObject * Object_getattr(Object *self, PyObject *name) {
    using namespace v8;

    PyObject *value = PyObject_GenericGetAttr((PyObject *)self, name);

    if(value != NULL)
        return value;

    char *_name = PyString_AsString(name);

    HandleScope handle_scope;

    v8::Context::Scope context_scope(self->context);

    Handle<Value> result = self->object->GetRealNamedProperty(String::New(_name));

    if(result.IsEmpty()) {
        // Exception already set by GetAttr
        return NULL;
    }

    // Have to reset exception raised by GetAttr
    PyErr_Clear();

    return wrap(self->context, self->object, result);
};

extern "C" PyObject * Function_call(Object *self, PyObject *args, PyObject *kw) {
    int argc = (int)PySequence_Size(args);

    v8::HandleScope handle_scope;

    v8::Handle<v8::Value> argv[argc];

    try {
        for(int i = 0; i < argc; i++) {
            argv[i] = py_to_json(PySequence_GetItem(args, i));
        }
    } catch (PyObject *bad_object) {
        PyObject *repr = PyObject_Repr(bad_object);

        char *repr_string;

        if(repr == NULL) {
            repr_string = "<unpresentable object>";
        } else {
            repr_string = PyString_AS_STRING(repr);
        }

        PyErr_Format(PyExc_TypeError, "cannot represent %s to javascript", repr_string);

        Py_XDECREF(repr);

        return NULL;
    }

    v8::Handle<v8::Value> result = self->object.As<v8::Function>()->Call(self->parent, argc, argv);

    return wrap(self->context, v8::Handle<v8::Object>(), result);
};

v8::Handle<v8::Value> py_to_json(PyObject *py) {
    if(py == Py_True)
        return v8::True();

    if(py == Py_False)
        return v8::False();

    if(py == Py_None)
        return v8::Null();

    if(PyInt_Check(py)) {
        long value = PyInt_AS_LONG(py);

        if(sizeof(long) == sizeof(int32_t)) {
            return v8::Integer::New(value);
        } else {
            if(-value < 1ll << 16 && value < 1ll << 16)
                return v8::Integer::New(value);

            if(value > 0ll && value < 1ll << 32)
                return v8::Integer::NewFromUnsigned(value);
        }
    }

    if(PyFloat_Check(py))
        return v8::Number::New(PyFloat_AS_DOUBLE(py));

    if(PyUnicode_Check(py)) {
        PyObject *py_string = PyUnicode_AsUTF8String(py);

        v8::Handle<v8::String> js_string = v8::String::New(PyString_AS_STRING(py_string));

        return js_string;
    }

    if(PyList_Check(py)) {
        uint32_t length = PyList_GET_SIZE(py);

        v8::Handle<v8::Array> array = v8::Array::New(length);

        for(uint32_t i = 0; i < length; i++) {
            v8::Handle<v8::Value> item = py_to_json(PyList_GET_ITEM(py, i));

            array->Set(i, item);
        }

        return array;
    }

    if(PyDict_Check(py)) {
        PyObject *key, *value;
        Py_ssize_t pos = 0;

        v8::Handle<v8::Object> object = v8::Object::New();

        while(PyDict_Next(py, &pos, &key, &value)) {
            v8::Handle<v8::Value> js_key = py_to_json(key);

            object->Set(js_key, py_to_json(value));
        }

        return object;
    }

    throw py;
};

PyObject * wrap(v8::Handle<v8::Context> context, v8::Handle<v8::Object> parent, v8::Handle<v8::Value> value) {
    if(value->IsInt32())
        return PyInt_FromLong(value->Int32Value());

    if(value->IsNumber())
        return PyFloat_FromDouble(value->NumberValue());

    if(value->IsBoolean())
        return PyBool_FromLong(value->BooleanValue());

    if(value->IsNull())
        Py_RETURN_NONE;

    if(value->IsUndefined()) {
        return Py_INCREF(Undefined), Undefined;
    }

    if(value->IsString()) {
        v8::String::Utf8Value utf_string(value);
        return PyUnicode_FromString(*utf_string);
    }

    Object *object;

    v8::Handle<v8::Value> wrapper = value->ToObject()->GetHiddenValue(v8::String::New("hemi::wrapper"));

    if(!wrapper.IsEmpty()) {
        object = (Object *)v8::External::Unwrap(wrapper);

        Py_INCREF(object);

        return (PyObject *)object;
    }

    if (value->IsFunction()) {
        object = PyObject_New(Object, &FunctionType);
    } else {
        object = PyObject_New(Object, &ObjectType);
    }

    object->context = v8::Persistent<v8::Context>::New(context);
    object->parent = v8::Persistent<v8::Object>::New(parent);
    object->object = v8::Persistent<v8::Object>::New(value.As<v8::Object>());

    object->object->SetHiddenValue(v8::String::New("hemi::wrapper"), v8::External::Wrap(object));

    return (PyObject *)object;
}

#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
inithemi(void)
{
    PyObject* m;

    if (PyType_Ready(&ContextType) < 0)
        return;

    if (PyType_Ready(&ObjectType) < 0)
        return;

    if (PyType_Ready(&FunctionType) < 0)
        return;

    if (PyType_Ready(&UndefinedType) < 0)
        return;

    Undefined = PyObject_New(PyObject, &UndefinedType);

    m = Py_InitModule3("hemi", module_methods,
                       "Lightweight V8 wrapper.");

    Py_INCREF(&ContextType);
    PyModule_AddObject(m, "Context", (PyObject *)&ContextType);
}
<commit_msg>Fix function call<commit_after>// -*- c-file-style: "cc-mode" -*-

#include "hemi.hpp"

extern "C" void Context_dealloc(Context* self) {
    self->context.Dispose();

    self->ob_type->tp_free((PyObject *)self);
}

extern "C" PyObject * Context_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) {
    Context *self = (Context *)subtype->tp_alloc(subtype, 0);

    if(self != NULL) {
        //HandleScope handle_scope;

        self->context = v8::Context::New();

        if(self->context.IsEmpty()) {
            Py_DECREF(self);
            return NULL;
        }
    }

    return (PyObject *)self;
}

extern "C" PyObject * Context_eval(Context *self, PyObject *args) {
    using namespace v8;

    char* _source;

    if(!PyArg_ParseTuple(args, "es", "utf-8", &_source))
        return NULL;

    HandleScope handle_scope;

    v8::Context::Scope context_scope(self->context);

    Handle<String> source = String::New(_source);

    PyMem_Free(_source);

    TryCatch trycatch;

    Handle<Script> script = Script::Compile(source);

    if(script.IsEmpty()) {
        Handle<Value> exception = trycatch.Exception();

        String::AsciiValue exception_str(exception);

        PyErr_SetString(PyExc_Exception, *exception_str);

        return NULL;
    }

    Handle<Value> result = script->Run();

    if(result.IsEmpty()) {
        Handle<Value> exception = trycatch.Exception();

        String::AsciiValue exception_str(exception);

        PyErr_SetString(PyExc_Exception, *exception_str);

        return NULL;
    }

    PyObject * py_result = wrap(self->context, Handle<v8::Object>(), result);

    return py_result;
}

extern "C" PyObject * Context_getlocals(Context *self, void *closure) {
    using namespace v8;

    v8::Context::Scope context_scope(self->context);

    HandleScope handle_scope;

    Handle<Value> object(self->context->Global());

    PyObject *wrapped = wrap(self->context, Handle<v8::Object>(), object);

    return wrapped;
}

extern "C" void Object_dealloc(Object* self) {
    v8::HandleScope handle_scope;

    self->object->DeleteHiddenValue(v8::String::New("hemi::wrapper"));

    self->object.Dispose();
    self->parent.Dispose();
    self->context.Dispose();

    self->ob_type->tp_free((PyObject *)self);
}

extern "C" PyObject * Object_getitem(Object *self, PyObject *item) {
    using namespace v8;

    if(PyUnicode_Check(item)) {
        PyObject *_item = PyUnicode_AsUTF8String(item);

        v8::Context::Scope context_scope(self->context);

        Handle<Value> result = self->object->GetRealNamedProperty(String::New(PyString_AS_STRING(_item)));

        Py_DECREF(_item);

        if(!result.IsEmpty())
            return wrap(self->context, self->object, result);
    }

    PyErr_SetObject(PyExc_KeyError, item);

    return NULL;
};

extern "C" PyObject * Object_getattr(Object *self, PyObject *name) {
    using namespace v8;

    PyObject *value = PyObject_GenericGetAttr((PyObject *)self, name);

    if(value != NULL)
        return value;

    char *_name = PyString_AsString(name);

    HandleScope handle_scope;

    v8::Context::Scope context_scope(self->context);

    Handle<Value> result = self->object->GetRealNamedProperty(String::New(_name));

    if(result.IsEmpty()) {
        // Exception already set by GetAttr
        return NULL;
    }

    // Have to reset exception raised by GetAttr
    PyErr_Clear();

    return wrap(self->context, self->object, result);
};

extern "C" PyObject * Function_call(Object *self, PyObject *args, PyObject *kw) {
    int argc = (int)PySequence_Size(args);

    v8::HandleScope handle_scope;

    v8::Context::Scope context_scope(self->context);

    v8::Handle<v8::Value> argv[argc];

    try {
        for(int i = 0; i < argc; i++) {
            argv[i] = py_to_json(PySequence_GetItem(args, i));
        }
    } catch (PyObject *bad_object) {
        PyObject *repr = PyObject_Repr(bad_object);

        char *repr_string;

        if(repr == NULL) {
            repr_string = "<unpresentable object>";
        } else {
            repr_string = PyString_AS_STRING(repr);
        }

        PyErr_Format(PyExc_TypeError, "cannot represent %s to javascript", repr_string);

        Py_XDECREF(repr);

        return NULL;
    }

    v8::Handle<v8::Value> result = self->object.As<v8::Function>()->Call(self->parent, argc, argv);

    return wrap(self->context, v8::Handle<v8::Object>(), result);
};

v8::Handle<v8::Value> py_to_json(PyObject *py) {
    if(py == Py_True)
        return v8::True();

    if(py == Py_False)
        return v8::False();

    if(py == Py_None)
        return v8::Null();

    if(PyInt_Check(py)) {
        long value = PyInt_AS_LONG(py);

        if(sizeof(long) == sizeof(int32_t)) {
            return v8::Integer::New(value);
        } else {
            if(-value < 1ll << 16 && value < 1ll << 16)
                return v8::Integer::New(value);

            if(value > 0ll && value < 1ll << 32)
                return v8::Integer::NewFromUnsigned(value);
        }
    }

    if(PyFloat_Check(py))
        return v8::Number::New(PyFloat_AS_DOUBLE(py));

    if(PyUnicode_Check(py)) {
        PyObject *py_string = PyUnicode_AsUTF8String(py);

        v8::Handle<v8::String> js_string = v8::String::New(PyString_AS_STRING(py_string));

        return js_string;
    }

    if(PyList_Check(py)) {
        uint32_t length = PyList_GET_SIZE(py);

        v8::Handle<v8::Array> array = v8::Array::New(length);

        for(uint32_t i = 0; i < length; i++) {
            v8::Handle<v8::Value> item = py_to_json(PyList_GET_ITEM(py, i));

            array->Set(i, item);
        }

        return array;
    }

    if(PyDict_Check(py)) {
        PyObject *key, *value;
        Py_ssize_t pos = 0;

        v8::Handle<v8::Object> object = v8::Object::New();

        while(PyDict_Next(py, &pos, &key, &value)) {
            v8::Handle<v8::Value> js_key = py_to_json(key);

            object->Set(js_key, py_to_json(value));
        }

        return object;
    }

    throw py;
};

PyObject * wrap(v8::Handle<v8::Context> context, v8::Handle<v8::Object> parent, v8::Handle<v8::Value> value) {
    if(value->IsInt32())
        return PyInt_FromLong(value->Int32Value());

    if(value->IsNumber())
        return PyFloat_FromDouble(value->NumberValue());

    if(value->IsBoolean())
        return PyBool_FromLong(value->BooleanValue());

    if(value->IsNull())
        Py_RETURN_NONE;

    if(value->IsUndefined()) {
        return Py_INCREF(Undefined), Undefined;
    }

    if(value->IsString()) {
        v8::String::Utf8Value utf_string(value);
        return PyUnicode_FromString(*utf_string);
    }

    Object *object;

    v8::Handle<v8::Value> wrapper = value->ToObject()->GetHiddenValue(v8::String::New("hemi::wrapper"));

    if(!wrapper.IsEmpty()) {
        object = (Object *)v8::External::Unwrap(wrapper);

        Py_INCREF(object);

        return (PyObject *)object;
    }

    if (value->IsFunction()) {
        object = PyObject_New(Object, &FunctionType);
    } else {
        object = PyObject_New(Object, &ObjectType);
    }

    object->context = v8::Persistent<v8::Context>::New(context);
    object->parent = v8::Persistent<v8::Object>::New(parent);
    object->object = v8::Persistent<v8::Object>::New(value.As<v8::Object>());

    object->object->SetHiddenValue(v8::String::New("hemi::wrapper"), v8::External::Wrap(object));

    return (PyObject *)object;
}

#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
inithemi(void)
{
    PyObject* m;

    if (PyType_Ready(&ContextType) < 0)
        return;

    if (PyType_Ready(&ObjectType) < 0)
        return;

    if (PyType_Ready(&FunctionType) < 0)
        return;

    if (PyType_Ready(&UndefinedType) < 0)
        return;

    Undefined = PyObject_New(PyObject, &UndefinedType);

    m = Py_InitModule3("hemi", module_methods,
                       "Lightweight V8 wrapper.");

    Py_INCREF(&ContextType);
    PyModule_AddObject(m, "Context", (PyObject *)&ContextType);
}
<|endoftext|>


<commit_before>#include "facepreprocessor.h"

#include <vector>
#include <algorithm>
#include <limits>
#include <cstdint>

#include <opencv2/imgproc/imgproc.hpp>

#include <QDebug>

static const double PI = std::atan(1.0) * 4;

using namespace cv;

FacePreprocessor::FacePreprocessor(FaceClassifiers classifiers, const Mat& input)  throw(std::invalid_argument)
    : input(input),
      result(Mat(input.rows, input.cols, CV_8UC1)),
      classifiers(classifiers)
{
    if (classifiers.face.get() == nullptr)
        throw std::invalid_argument("face classifier");
    else if (classifiers.face->empty())
        throw std::invalid_argument("face classifier");
    else if (classifiers.eye.get() == nullptr)
        throw std::invalid_argument("eye classifier");
    else if (classifiers.eye->empty())
        throw std::invalid_argument("eye classifier");
    else if (classifiers.eyePair.get() == nullptr)
        throw std::invalid_argument("eyepair classifier");
    else if (classifiers.eyePair->empty())
        throw std::invalid_argument("eyepair classifier");
    else if (classifiers.eyeLeft.get() == nullptr)
        throw std::invalid_argument("left eye classifier");
    else if (classifiers.eyeLeft->empty())
        throw std::invalid_argument("left eye classifier");
    else if (classifiers.eyeRight.get() == nullptr)
        throw std::invalid_argument("right eye classifier");
    else if (classifiers.eyeRight->empty())
        throw std::invalid_argument("right eye classifier");
}

unsigned int FacePreprocessor::GetMinSize() const
{
    int minDim = std::min(input.rows, input.cols);
    return static_cast<unsigned int>(minDim / 5.0);
}

Rect FacePreprocessor::LargestRect(const std::vector<Rect>& rects)
{
    if(rects.empty())
        return Rect();
    Rect largest = *std::max_element(rects.begin(), rects.end(), [](const Rect& a, const Rect& b)
    {
        return a.area() < b.area();
    }
    );
    return largest;
}

const double FacePreprocessor::MAX_ROTATE_ANGLE = 20.0;

double FacePreprocessor::GetRotation(cv::Rect left, cv::Rect right)
{
    Point direction;
    direction.x = right.x - left.x;
    direction.y = right.y - left.y;
    double angle = std::atan2(direction.y, direction.x) * 180.0 / PI;
    return angle;
}

std::vector<Rect> FacePreprocessor::GetEyesAlternateMethod()
{
    static std::vector<Rect> empty;
    std::vector<Rect> eyes;
    eyes.reserve(2);
    classifiers.eyePair->detectMultiScale(result, eyes, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(eyes.empty())
        return empty;
    qDebug() << "eye pair was found";
    rectangle(result, eyes.front(), 1);

    std::vector<Rect> lefts;
    std::vector<Rect> rights;
    Rect cRect = eyes.front();
    cRect.width /= 2;
    classifiers.eyeLeft->detectMultiScale(result(cRect), lefts, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(lefts.empty())
    {
        qDebug () << "left wasnt found";
        return empty;
    }
    cRect.x += cRect.width;
    classifiers.eyeLeft->detectMultiScale(result(cRect), rights, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(rights.empty())
    {
        qDebug () << "right wasnt found";
        return empty;
    }
    rights.front().x += cRect.width;

    gotEyes = true;

    lefts.front().x += eyes.front().x;
    lefts.front().y += eyes.front().y;
    rights.front().x += eyes.front().x;
    rights.front().y += eyes.front().y;
    rectangle(result, lefts.front(), 1);
    rectangle(result, rights.front(), 1);

    eyes.clear();
    eyes.push_back(lefts.front());
    eyes.push_back(rights.front());
    return eyes;
}

std::vector<Rect> FacePreprocessor::GetEyes()
{
    int maxSize = static_cast<int>(std::ceil(std::max(result.rows, result.cols) / 6.0));
    int minSize = std::max(static_cast<int>(std::floor(std::min(result.rows, result.cols) / 20.0)), 5);
    Rect upperHalfOfFace(0, 0, face.width, static_cast<int>(face.height / 1.8));
    std::vector<Rect> eyes;
    std::vector<Rect> eyePairR;
    //classifiers.eyePair->detectMultiScale(result(upperHalfOfFace), eyePairR, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(eyePairR.empty())
    {
        classifiers.eye->detectMultiScale(result(upperHalfOfFace), eyes, 1.1, 6, 0, Size(minSize, minSize), Size(maxSize, maxSize));
    }
    else
    {
        classifiers.eye->detectMultiScale(result(eyePairR.front()), eyes, 1.1, 6, 0, Size(minSize, minSize), Size(maxSize, maxSize));
        rectangle(result, eyePairR.front(), 255);
    }
    for (auto eye : eyes)
    {
        if(!eyePairR.empty())
        {
            eye.x += eyePairR.front().x;
            eye.y += eyePairR.front().y;
        }
        rectangle(result, eye, 1);
    }
    if(eyes.size() < 2)
    {
        qDebug() << "only" << eyes.size() << "eyes were found";
        eyes.clear();
        return eyes;
    }
    gotEyes = true;

    if(eyes.size() > 2)
    {
        // finding the pair with lowest angle
        std::vector<std::pair<uint16_t, uint16_t>> helper;
        helper.reserve(eyes.size() * eyes.size() - eyes.size());
        for(auto i = eyes.begin(); i != eyes.end(); i++)
        {
            for(auto j = eyes.begin(); j != eyes.end(); j++)
            {
                if (i != j)
                    helper.push_back(std::make_pair(std::distance(eyes.begin(), i), std::distance(eyes.begin(), j)));
            }
        }

        std::sort(helper.begin(), helper.end(), [&eyes](const std::pair<uint16_t, uint16_t>& a, const std::pair<uint16_t, uint16_t>& b)
        {
            double angleA = std::abs(GetRotation(eyes[a.first], eyes[a.second]));
            double angleB = std::abs(GetRotation(eyes[b.first], eyes[b.second]));
            return angleA < angleB;
        });

        assert(helper.front().first != helper.front().second);

        std::swap(eyes[0], eyes[helper.front().first]);
        std::swap(eyes[1], eyes[helper.front().second]);
    }

    std::sort(eyes.begin(), eyes.begin() + 2, [](const Rect& a, const Rect& b) { return a.x < b.x; });
    eyes.resize(2);
    return eyes;
}

void FacePreprocessor::RotateFace()
{
    std::vector<Rect> eyes = GetEyes();
    if(eyes.size() < 2)
    {
        return;
    }

    double angle = GetRotation(eyes[0], eyes[1]);
    qDebug() << "rotation angle: " << angle;
    if (std::abs(angle) < std::numeric_limits<double>::epsilon() * 3 || std::abs(angle) > MAX_ROTATE_ANGLE)
        return;

    int size = std::max(result.cols, result.rows);
    int fullSize = std::max(normalized.cols, normalized.rows);
    Point2f pt(size/2.0f + face.x, size/2.0f + face.y);
    Mat r = getRotationMatrix2D(pt, angle, 1.0);

    warpAffine(normalized, rotated, r, Size(fullSize, fullSize), CV_INTER_LANCZOS4);

    result = rotated(face);
}

void FacePreprocessor::ScaleFace()
{
    Rect aspected = face;
    if(face.width < face.height)
    {
        aspected.width = face.height;
    }
    else
    {
        aspected.height = face.width;
    }

    Mat scaled = result.clone();

    copyMakeBorder(scaled, scaled, 0, aspected.height, 0, aspected.width, BORDER_REPLICATE);

    aspected.x = 0;
    aspected.y = 0;

    result = scaled(aspected);
    resize(result, result, Size(512, 512), 0.0, 0.0, CV_INTER_LANCZOS4);
}

double FacePreprocessor::GetAccuracy() const
{
    double accuracy = 0.0;
    if(face.width > 0 && face.height > 0)
        accuracy += 0.5;
    if(gotEyes)
        accuracy += 0.5;
    return accuracy;
}

Mat FacePreprocessor::Preprocess() throw (NoFaceFoundException)
{
    if(input.type() == CV_8UC3)
        cvtColor(input, result, CV_BGR2GRAY);
    else
        result = input;
    equalizeHist(result, normalized);

    result = normalized;

    std::vector<Rect> faces;
    Size minSize(GetMinSize(), GetMinSize());
    classifiers.face->detectMultiScale(result, faces, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT, minSize);

    if (!faces.empty())
    {
        face = LargestRect(faces);

        result = result(face);
    }
    else
    {
        throw NoFaceFoundException();
    }

    RotateFace();

    static uint64_t cntr = 0;
    static uint64_t cntr2 = 0;

    cntr2++;

    if(!gotEyes)
        qDebug() << "no eyes were found on the face -- this is odd :(" << ++cntr << "/" << cntr2;
    else
        qDebug() << "is rotated? " << !rotated.empty() << (cntr2 - cntr) << "/" << cntr2;

    ScaleFace();

    return result;
}
<commit_msg>debug rectangles are only visible if MARK_FOUND_FEATURES is true<commit_after>#include "facepreprocessor.h"

#include <vector>
#include <algorithm>
#include <limits>
#include <cstdint>

#include <opencv2/imgproc/imgproc.hpp>

#include <QDebug>

static const double PI = std::atan(1.0) * 4;

using namespace cv;

static const bool MARK_FOUND_FEATURES = false;

FacePreprocessor::FacePreprocessor(FaceClassifiers classifiers, const Mat& input)  throw(std::invalid_argument)
    : input(input),
      result(Mat(input.rows, input.cols, CV_8UC1)),
      classifiers(classifiers)
{
    if (classifiers.face.get() == nullptr)
        throw std::invalid_argument("face classifier");
    else if (classifiers.face->empty())
        throw std::invalid_argument("face classifier");
    else if (classifiers.eye.get() == nullptr)
        throw std::invalid_argument("eye classifier");
    else if (classifiers.eye->empty())
        throw std::invalid_argument("eye classifier");
    else if (classifiers.eyePair.get() == nullptr)
        throw std::invalid_argument("eyepair classifier");
    else if (classifiers.eyePair->empty())
        throw std::invalid_argument("eyepair classifier");
    else if (classifiers.eyeLeft.get() == nullptr)
        throw std::invalid_argument("left eye classifier");
    else if (classifiers.eyeLeft->empty())
        throw std::invalid_argument("left eye classifier");
    else if (classifiers.eyeRight.get() == nullptr)
        throw std::invalid_argument("right eye classifier");
    else if (classifiers.eyeRight->empty())
        throw std::invalid_argument("right eye classifier");
}

unsigned int FacePreprocessor::GetMinSize() const
{
    int minDim = std::min(input.rows, input.cols);
    return static_cast<unsigned int>(minDim / 5.0);
}

Rect FacePreprocessor::LargestRect(const std::vector<Rect>& rects)
{
    if(rects.empty())
        return Rect();
    Rect largest = *std::max_element(rects.begin(), rects.end(), [](const Rect& a, const Rect& b)
    {
        return a.area() < b.area();
    }
    );
    return largest;
}

const double FacePreprocessor::MAX_ROTATE_ANGLE = 20.0;

double FacePreprocessor::GetRotation(cv::Rect left, cv::Rect right)
{
    Point direction;
    direction.x = right.x - left.x;
    direction.y = right.y - left.y;
    double angle = std::atan2(direction.y, direction.x) * 180.0 / PI;
    return angle;
}

std::vector<Rect> FacePreprocessor::GetEyesAlternateMethod()
{
    static std::vector<Rect> empty;
    std::vector<Rect> eyes;
    eyes.reserve(2);
    classifiers.eyePair->detectMultiScale(result, eyes, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(eyes.empty())
        return empty;
    qDebug() << "eye pair was found";
    if (MARK_FOUND_FEATURES)
        rectangle(result, eyes.front(), 1);

    std::vector<Rect> lefts;
    std::vector<Rect> rights;
    Rect cRect = eyes.front();
    cRect.width /= 2;
    classifiers.eyeLeft->detectMultiScale(result(cRect), lefts, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(lefts.empty())
    {
        qDebug () << "left wasnt found";
        return empty;
    }
    cRect.x += cRect.width;
    classifiers.eyeLeft->detectMultiScale(result(cRect), rights, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(rights.empty())
    {
        qDebug () << "right wasnt found";
        return empty;
    }
    rights.front().x += cRect.width;

    gotEyes = true;

    lefts.front().x += eyes.front().x;
    lefts.front().y += eyes.front().y;
    rights.front().x += eyes.front().x;
    rights.front().y += eyes.front().y;
    if (MARK_FOUND_FEATURES)
    {
        rectangle(result, lefts.front(), 1);
        rectangle(result, rights.front(), 1);
    }

    eyes.clear();
    eyes.push_back(lefts.front());
    eyes.push_back(rights.front());
    return eyes;
}

std::vector<Rect> FacePreprocessor::GetEyes()
{
    int maxSize = static_cast<int>(std::ceil(std::max(result.rows, result.cols) / 6.0));
    int minSize = std::max(static_cast<int>(std::floor(std::min(result.rows, result.cols) / 20.0)), 5);
    Rect upperHalfOfFace(0, 0, face.width, static_cast<int>(face.height / 1.8));
    std::vector<Rect> eyes;
    std::vector<Rect> eyePairR;
    //classifiers.eyePair->detectMultiScale(result(upperHalfOfFace), eyePairR, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(eyePairR.empty())
    {
        classifiers.eye->detectMultiScale(result(upperHalfOfFace), eyes, 1.1, 6, 0, Size(minSize, minSize), Size(maxSize, maxSize));
    }
    else
    {
        classifiers.eye->detectMultiScale(result(eyePairR.front()), eyes, 1.1, 6, 0, Size(minSize, minSize), Size(maxSize, maxSize));
        if (MARK_FOUND_FEATURES)
            rectangle(result, eyePairR.front(), 255);
    }
    for (auto eye : eyes)
    {
        if(!eyePairR.empty())
        {
            eye.x += eyePairR.front().x;
            eye.y += eyePairR.front().y;
        }
        if (MARK_FOUND_FEATURES)
            rectangle(result, eye, 1);
    }
    if(eyes.size() < 2)
    {
        qDebug() << "only" << eyes.size() << "eyes were found";
        eyes.clear();
        return eyes;
    }
    gotEyes = true;

    if(eyes.size() > 2)
    {
        // finding the pair with lowest angle
        std::vector<std::pair<uint16_t, uint16_t>> helper;
        helper.reserve(eyes.size() * eyes.size() - eyes.size());
        for(auto i = eyes.begin(); i != eyes.end(); i++)
        {
            for(auto j = eyes.begin(); j != eyes.end(); j++)
            {
                if (i != j)
                    helper.push_back(std::make_pair(std::distance(eyes.begin(), i), std::distance(eyes.begin(), j)));
            }
        }

        std::sort(helper.begin(), helper.end(), [&eyes](const std::pair<uint16_t, uint16_t>& a, const std::pair<uint16_t, uint16_t>& b)
        {
            double angleA = std::abs(GetRotation(eyes[a.first], eyes[a.second]));
            double angleB = std::abs(GetRotation(eyes[b.first], eyes[b.second]));
            return angleA < angleB;
        });

        assert(helper.front().first != helper.front().second);

        std::swap(eyes[0], eyes[helper.front().first]);
        std::swap(eyes[1], eyes[helper.front().second]);
    }

    std::sort(eyes.begin(), eyes.begin() + 2, [](const Rect& a, const Rect& b) { return a.x < b.x; });
    eyes.resize(2);
    return eyes;
}

void FacePreprocessor::RotateFace()
{
    std::vector<Rect> eyes = GetEyes();
    if(eyes.size() < 2)
    {
        return;
    }

    double angle = GetRotation(eyes[0], eyes[1]);
    qDebug() << "rotation angle: " << angle;
    if (std::abs(angle) < std::numeric_limits<double>::epsilon() * 3 || std::abs(angle) > MAX_ROTATE_ANGLE)
        return;

    int size = std::max(result.cols, result.rows);
    int fullSize = std::max(normalized.cols, normalized.rows);
    Point2f pt(size/2.0f + face.x, size/2.0f + face.y);
    Mat r = getRotationMatrix2D(pt, angle, 1.0);

    warpAffine(normalized, rotated, r, Size(fullSize, fullSize), CV_INTER_LANCZOS4);

    result = rotated(face);
}

void FacePreprocessor::ScaleFace()
{
    Rect aspected = face;
    if(face.width < face.height)
    {
        aspected.width = face.height;
    }
    else
    {
        aspected.height = face.width;
    }

    Mat scaled = result.clone();

    copyMakeBorder(scaled, scaled, 0, aspected.height, 0, aspected.width, BORDER_REPLICATE);

    aspected.x = 0;
    aspected.y = 0;

    result = scaled(aspected);
    resize(result, result, Size(512, 512), 0.0, 0.0, CV_INTER_LANCZOS4);
}

double FacePreprocessor::GetAccuracy() const
{
    double accuracy = 0.0;
    if(face.width > 0 && face.height > 0)
        accuracy += 0.5;
    if(gotEyes)
        accuracy += 0.5;
    return accuracy;
}

Mat FacePreprocessor::Preprocess() throw (NoFaceFoundException)
{
    if(input.type() == CV_8UC3)
        cvtColor(input, result, CV_BGR2GRAY);
    else
        result = input;
    equalizeHist(result, normalized);

    result = normalized;

    std::vector<Rect> faces;
    Size minSize(GetMinSize(), GetMinSize());
    classifiers.face->detectMultiScale(result, faces, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT, minSize);

    if (!faces.empty())
    {
        face = LargestRect(faces);

        result = result(face);
    }
    else
    {
        throw NoFaceFoundException();
    }

    RotateFace();

    static uint64_t cntr = 0;
    static uint64_t cntr2 = 0;

    cntr2++;

    if(!gotEyes)
        qDebug() << "no eyes were found on the face -- this is odd :(" << ++cntr << "/" << cntr2;
    else
        qDebug() << "is rotated? " << !rotated.empty() << (cntr2 - cntr) << "/" << cntr2;

    ScaleFace();

    return result;
}
<|endoftext|>