<commit_before>#include "mitkConcentrationCurveGenerator.h"
#include "mitkConvertToConcentrationTurboFlashFunctor.h"
#include "mitkConvertT2ConcentrationFunctor.h"
#include "mitkConvertToConcentrationViaT1Functor.h"
#include "mitkImageTimeSelector.h"
#include "mitkImageCast.h"
#include "mitkITKImageImport.h"
#include "mitkModelBase.h"
#include "mitkExtractTimeGrid.h"
#include "mitkArbitraryTimeGeometry.h"
#include "itkNaryAddImageFilter.h"
#include "mitkImageAccessByItk.h"
#include "itkImageIOBase.h"
#include "itkBinaryFunctorImageFilter.h"
#include "itkTernaryFunctorImageFilter.h"
#include <itkExtractImageFilter.h>
#include "itkMeanProjectionImageFilter.h"

mitk::ConcentrationCurveGenerator::ConcentrationCurveGenerator() : m_isT2weightedImage(false), m_isTurboFlashSequence(false),
    m_AbsoluteSignalEnhancement(false), m_RelativeSignalEnhancement(0.0), m_UsingT1Map(false), m_Factor(0.0), m_RecoveryTime(0.0), m_RelaxationTime(0.0),
    m_Relaxivity(0.0), m_FlipAngle(0.0), m_T2Factor(0.0), m_T2EchoTime(0.0)
{
}

mitk::ConcentrationCurveGenerator::~ConcentrationCurveGenerator()
{

}

mitk::Image::Pointer mitk::ConcentrationCurveGenerator::GetConvertedImage()
{
    if(this->m_DynamicImage.IsNull())
    {
        itkExceptionMacro( << "Dynamic Image not set!");
    }
    else {
    Convert();
    }
    return m_ConvertedImage;

}

void mitk::ConcentrationCurveGenerator::Convert()
{

    mitk::Image::Pointer tempImage = mitk::Image::New();
    mitk::PixelType pixeltype = mitk::MakeScalarPixelType<double>();

    tempImage->Initialize(pixeltype,*this->m_DynamicImage->GetTimeGeometry());

    mitk::TimeGeometry::Pointer timeGeometry = (this->m_DynamicImage->GetTimeGeometry())->Clone();
    tempImage->SetTimeGeometry(timeGeometry);

    PrepareBaselineImage();
    mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New();
    imageTimeSelector->SetInput(this->m_DynamicImage);

    for(unsigned int i = 0; i< this->m_DynamicImage->GetTimeSteps(); ++i)
    {
        imageTimeSelector->SetTimeNr(i);
        imageTimeSelector->UpdateLargestPossibleRegion();

        mitk::Image::Pointer mitkInputImage = imageTimeSelector->GetOutput();
        mitk::Image::Pointer outputImage = mitk::Image::New();

        outputImage = ConvertSignalToConcentrationCurve(mitkInputImage,this->m_BaselineImage);

        mitk::ImageReadAccessor accessor(outputImage);
        tempImage->SetVolume(accessor.GetData(), i);
    }

    this->m_ConvertedImage = tempImage;

}

void mitk::ConcentrationCurveGenerator::PrepareBaselineImage()
{

  mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New();
  imageTimeSelector->SetInput(this->m_DynamicImage);
  imageTimeSelector->SetTimeNr(0);
  imageTimeSelector->UpdateLargestPossibleRegion();
  mitk::Image::Pointer baselineImage;
  baselineImage = imageTimeSelector->GetOutput();

  if (m_BaselineStartTimeStep == m_BaselineEndTimeStep)
  {
    this->m_BaselineImage = imageTimeSelector->GetOutput();
  }
  else
  {
    try
    {
      AccessFixedDimensionByItk(this->m_DynamicImage, mitk::ConcentrationCurveGenerator::CalculateAverageBaselineImage, 4);
    }
    catch (itk::ExceptionObject & err)
    {
      std::cerr << "ExceptionObject in ConcentrationCurveGenerator::CalculateAverageBaselineImage caught!" << std::endl;
      std::cerr << err << std::endl;
    }
  }
}

template<class TPixel>
void mitk::ConcentrationCurveGenerator::CalculateAverageBaselineImage(const itk::Image<TPixel, 4> *itkBaselineImage)
{
  if (itkBaselineImage == NULL)
  {
    mitkThrow() << "Error in ConcentrationCurveGenerator::CalculateAverageBaselineImage. Input image is NULL.";
  }
  if (m_BaselineStartTimeStep > m_BaselineEndTimeStep)
  {
    mitkThrow() << "Error in ConcentrationCurveGenerator::CalculateAverageBaselineImage. End time point is before start time point.";
  }

  typedef itk::Image<TPixel, 4> TPixel4DImageType;
  typedef itk::Image<TPixel, 3> TPixel3DImageType;
  typedef itk::Image<double, 3> Double3DImageType;
  typedef itk::Image<double, 4> Double4DImageType;
  typedef itk::ExtractImageFilter<TPixel4DImageType, TPixel4DImageType> ExtractImageFilterType;
  typedef itk::ExtractImageFilter<Double4DImageType, Double3DImageType> Extract3DImageFilterType;
  typedef itk::MeanProjectionImageFilter<TPixel4DImageType,Double4DImageType> MeanProjectionImageFilterType;

  typename MeanProjectionImageFilterType::Pointer MeanProjectionImageFilter = MeanProjectionImageFilterType::New();
  typename Extract3DImageFilterType::Pointer Extract3DImageFilter = Extract3DImageFilterType::New();
  typename TPixel4DImageType::RegionType region_input = itkBaselineImage->GetLargestPossibleRegion();

  if (m_BaselineEndTimeStep > region_input.GetSize()[3])
  {
    mitkThrow() << "Error in ConcentrationCurveGenerator::CalculateAverageBaselineImage. End time point is larger than total number of time points.";
  }

  ExtractImageFilterType::Pointer ExtractFilter = ExtractImageFilterType::New();
  typename TPixel4DImageType::Pointer baselineTimeFrameImage = TPixel4DImageType::New();
  typename TPixel4DImageType::RegionType extractionRegion;
  typename TPixel4DImageType::SizeType size_input_aux = region_input.GetSize();
  size_input_aux[3] = m_BaselineEndTimeStep - m_BaselineStartTimeStep+1;
  typename TPixel4DImageType::IndexType start_input_aux = region_input.GetIndex();
  start_input_aux[3] = m_BaselineStartTimeStep;
  extractionRegion.SetSize(size_input_aux);
  extractionRegion.SetIndex(start_input_aux);
  ExtractFilter->SetExtractionRegion(extractionRegion);
  ExtractFilter->SetInput(itkBaselineImage);
  ExtractFilter->SetDirectionCollapseToSubmatrix();
  try
  {
    ExtractFilter->Update();
  }
  catch (itk::ExceptionObject & err)
  {
    std::cerr << "ExceptionObject caught!" << std::endl;
    std::cerr << err << std::endl;
  }
  baselineTimeFrameImage = ExtractFilter->GetOutput();
  MeanProjectionImageFilter->SetProjectionDimension(3);
  MeanProjectionImageFilter->SetInput(baselineTimeFrameImage);
  try
  {
    MeanProjectionImageFilter->Update();
  }
  catch (itk::ExceptionObject & err)
  {
    std::cerr << "ExceptionObject caught!" << std::endl;
    std::cerr << err << std::endl;
  }
  Extract3DImageFilter->SetInput(MeanProjectionImageFilter->GetOutput());
  size_input_aux[3] = 0;
  start_input_aux[3] = 0;
  extractionRegion.SetSize(size_input_aux);
  extractionRegion.SetIndex(start_input_aux);
  Extract3DImageFilter->SetExtractionRegion(extractionRegion);
  Extract3DImageFilter->SetDirectionCollapseToSubmatrix();
  try
  {
    Extract3DImageFilter->Update();
  }
  catch (itk::ExceptionObject & err)
  {
    std::cerr << "ExceptionObject caught!" << std::endl;
    std::cerr << err << std::endl;
  }

  Image::Pointer mitkBaselineImage = Image::New();
  CastToMitkImage(Extract3DImageFilter->GetOutput(), mitkBaselineImage);
  this->m_BaselineImage = mitkBaselineImage;
}

mitk::Image::Pointer mitk::ConcentrationCurveGenerator::ConvertSignalToConcentrationCurve(const mitk::Image* inputImage,const mitk::Image* baselineImage)
{
  mitk::PixelType m_PixelType = inputImage->GetPixelType();
  AccessTwoImagesFixedDimensionByItk(inputImage, baselineImage, mitk::ConcentrationCurveGenerator::convertToConcentration, 3);
  return m_ConvertSignalToConcentrationCurve_OutputImage;

}

template<class TPixel_input, class TPixel_baseline>
mitk::Image::Pointer mitk::ConcentrationCurveGenerator::convertToConcentration(const itk::Image<TPixel_input, 3> *itkInputImage, const itk::Image<TPixel_baseline, 3> *itkBaselineImage)
{
    typedef itk::Image<TPixel_input, 3> InputImageType;
    typedef itk::Image<TPixel_baseline, 3> BaselineImageType;
    typedef itk::Image<double, 3> DoubleImageType;

    typename DoubleImageType::Pointer itkDoubleInputImage = DoubleImageType::New();
    typename DoubleImageType::Pointer itkDoubleBaselineImage = DoubleImageType::New();

    typedef itk::CastImageFilter<InputImageType, DoubleImageType> CastInputImageToDoubleImageFilterType;
    typename CastInputImageToDoubleImageFilterType::Pointer CastInputImageToDoubleImageFilter = CastInputImageToDoubleImageFilterType::New();
    CastInputImageToDoubleImageFilter->SetInput(itkInputImage);
    CastInputImageToDoubleImageFilter->Update();
    itkDoubleInputImage = CastInputImageToDoubleImageFilter->GetOutput();

    typedef itk::CastImageFilter<BaselineImageType, DoubleImageType> CastBaselineImageToDoubleImageFilterType;
    typename CastBaselineImageToDoubleImageFilterType::Pointer CastBaselineImageToDoubleImageFilter = CastBaselineImageToDoubleImageFilterType::New();
    CastBaselineImageToDoubleImageFilter->SetInput(itkBaselineImage);
    CastBaselineImageToDoubleImageFilter->Update();
    itkDoubleBaselineImage = CastBaselineImageToDoubleImageFilter->GetOutput();

    if (this->m_isT2weightedImage)
    {
        typedef mitk::ConvertT2ConcentrationFunctor <double, double, double> ConversionFunctorT2Type;
        typedef itk::BinaryFunctorImageFilter<DoubleImageType, DoubleImageType, ConvertedImageType, ConversionFunctorT2Type> FilterT2Type;

        ConversionFunctorT2Type ConversionT2Functor;
        ConversionT2Functor.initialize(this->m_T2Factor, this->m_T2EchoTime);

        typename FilterT2Type::Pointer ConversionT2Filter = FilterT2Type::New();

        ConversionT2Filter->SetFunctor(ConversionT2Functor);
        ConversionT2Filter->SetInput1(itkDoubleInputImage);
        ConversionT2Filter->SetInput2(itkDoubleBaselineImage);

        ConversionT2Filter->Update();

        m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionT2Filter->GetOutput())->Clone();
      }

    else
    {
        if(this->m_isTurboFlashSequence)
        {
            typedef mitk::ConvertToConcentrationTurboFlashFunctor <double, double, double> ConversionFunctorTurboFlashType;
            typedef itk::BinaryFunctorImageFilter<DoubleImageType, DoubleImageType, ConvertedImageType, ConversionFunctorTurboFlashType> FilterTurboFlashType;

            ConversionFunctorTurboFlashType ConversionTurboFlashFunctor;
            ConversionTurboFlashFunctor.initialize(this->m_RelaxationTime, this->m_Relaxivity, this->m_RecoveryTime);

            typename FilterTurboFlashType::Pointer ConversionTurboFlashFilter = FilterTurboFlashType::New();

            ConversionTurboFlashFilter->SetFunctor(ConversionTurboFlashFunctor);
            ConversionTurboFlashFilter->SetInput1(itkDoubleInputImage);
            ConversionTurboFlashFilter->SetInput2(itkDoubleBaselineImage);

            ConversionTurboFlashFilter->Update();
            m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionTurboFlashFilter->GetOutput())->Clone();

        }
        else if(this->m_UsingT1Map)
        {
            typename DoubleImageType::Pointer itkT10Image = DoubleImageType::New();
            mitk::CastToItkImage(m_T10Image, itkT10Image);

            typedef mitk::ConvertToConcentrationViaT1CalcFunctor <double, double, double, double> ConvertToConcentrationViaT1CalcFunctorType;
            typedef itk::TernaryFunctorImageFilter<DoubleImageType, DoubleImageType, DoubleImageType,ConvertedImageType, ConvertToConcentrationViaT1CalcFunctorType> FilterT1MapType;

            ConvertToConcentrationViaT1CalcFunctorType ConversionT1MapFunctor;
            ConversionT1MapFunctor.initialize(this->m_Relaxivity, this->m_RecoveryTime, this->m_FlipAngle);

            typename FilterT1MapType::Pointer ConversionT1MapFilter = FilterT1MapType::New();

            ConversionT1MapFilter->SetFunctor(ConversionT1MapFunctor);
            ConversionT1MapFilter->SetInput1(itkDoubleInputImage);
            ConversionT1MapFilter->SetInput2(itkDoubleBaselineImage);
            ConversionT1MapFilter->SetInput3(itkT10Image);

            ConversionT1MapFilter->Update();
            m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionT1MapFilter->GetOutput())->Clone();

        }

        else if(this->m_AbsoluteSignalEnhancement)
        {
            typedef mitk::ConvertToConcentrationAbsoluteFunctor <double, double, double> ConversionFunctorAbsoluteType;
            typedef itk::BinaryFunctorImageFilter<DoubleImageType, DoubleImageType, ConvertedImageType, ConversionFunctorAbsoluteType> FilterAbsoluteType;

            ConversionFunctorAbsoluteType ConversionAbsoluteFunctor;
            ConversionAbsoluteFunctor.initialize(this->m_Factor);

            typename FilterAbsoluteType::Pointer ConversionAbsoluteFilter = FilterAbsoluteType::New();

            ConversionAbsoluteFilter->SetFunctor(ConversionAbsoluteFunctor);
            ConversionAbsoluteFilter->SetInput1(itkDoubleInputImage);
            ConversionAbsoluteFilter->SetInput2(itkDoubleBaselineImage);

            ConversionAbsoluteFilter->Update();

            m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionAbsoluteFilter->GetOutput())->Clone();
        }

        else if(this->m_RelativeSignalEnhancement)
        {
            typedef mitk::ConvertToConcentrationRelativeFunctor <double, double, double> ConversionFunctorRelativeType;
            typedef itk::BinaryFunctorImageFilter<DoubleImageType, DoubleImageType, ConvertedImageType, ConversionFunctorRelativeType> FilterRelativeType;

            ConversionFunctorRelativeType ConversionRelativeFunctor;
            ConversionRelativeFunctor.initialize(this->m_Factor);

            typename FilterRelativeType::Pointer ConversionRelativeFilter = FilterRelativeType::New();

            ConversionRelativeFilter->SetFunctor(ConversionRelativeFunctor);
            ConversionRelativeFilter->SetInput1(itkDoubleInputImage);
            ConversionRelativeFilter->SetInput2(itkDoubleBaselineImage);

            ConversionRelativeFilter->Update();

            m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionRelativeFilter->GetOutput())->Clone();
        }

    }
    return m_ConvertSignalToConcentrationCurve_OutputImage;

}

<commit_msg>Add brackets for better readability.<commit_after>#include "mitkConcentrationCurveGenerator.h"
#include "mitkConvertToConcentrationTurboFlashFunctor.h"
#include "mitkConvertT2ConcentrationFunctor.h"
#include "mitkConvertToConcentrationViaT1Functor.h"
#include "mitkImageTimeSelector.h"
#include "mitkImageCast.h"
#include "mitkITKImageImport.h"
#include "mitkModelBase.h"
#include "mitkExtractTimeGrid.h"
#include "mitkArbitraryTimeGeometry.h"
#include "itkNaryAddImageFilter.h"
#include "mitkImageAccessByItk.h"
#include "itkImageIOBase.h"
#include "itkBinaryFunctorImageFilter.h"
#include "itkTernaryFunctorImageFilter.h"
#include <itkExtractImageFilter.h>
#include "itkMeanProjectionImageFilter.h"

mitk::ConcentrationCurveGenerator::ConcentrationCurveGenerator() : m_isT2weightedImage(false), m_isTurboFlashSequence(false),
    m_AbsoluteSignalEnhancement(false), m_RelativeSignalEnhancement(0.0), m_UsingT1Map(false), m_Factor(0.0), m_RecoveryTime(0.0), m_RelaxationTime(0.0),
    m_Relaxivity(0.0), m_FlipAngle(0.0), m_T2Factor(0.0), m_T2EchoTime(0.0)
{
}

mitk::ConcentrationCurveGenerator::~ConcentrationCurveGenerator()
{

}

mitk::Image::Pointer mitk::ConcentrationCurveGenerator::GetConvertedImage()
{
    if(this->m_DynamicImage.IsNull())
    {
        itkExceptionMacro( << "Dynamic Image not set!");
    }
    else {
    Convert();
    }
    return m_ConvertedImage;

}

void mitk::ConcentrationCurveGenerator::Convert()
{

    mitk::Image::Pointer tempImage = mitk::Image::New();
    mitk::PixelType pixeltype = mitk::MakeScalarPixelType<double>();

    tempImage->Initialize(pixeltype,*this->m_DynamicImage->GetTimeGeometry());

    mitk::TimeGeometry::Pointer timeGeometry = (this->m_DynamicImage->GetTimeGeometry())->Clone();
    tempImage->SetTimeGeometry(timeGeometry);

    PrepareBaselineImage();
    mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New();
    imageTimeSelector->SetInput(this->m_DynamicImage);

    for(unsigned int i = 0; i< this->m_DynamicImage->GetTimeSteps(); ++i)
    {
        imageTimeSelector->SetTimeNr(i);
        imageTimeSelector->UpdateLargestPossibleRegion();

        mitk::Image::Pointer mitkInputImage = imageTimeSelector->GetOutput();
        mitk::Image::Pointer outputImage = mitk::Image::New();

        outputImage = ConvertSignalToConcentrationCurve(mitkInputImage,this->m_BaselineImage);

        mitk::ImageReadAccessor accessor(outputImage);
        tempImage->SetVolume(accessor.GetData(), i);
    }

    this->m_ConvertedImage = tempImage;

}

void mitk::ConcentrationCurveGenerator::PrepareBaselineImage()
{

  mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New();
  imageTimeSelector->SetInput(this->m_DynamicImage);
  imageTimeSelector->SetTimeNr(0);
  imageTimeSelector->UpdateLargestPossibleRegion();
  mitk::Image::Pointer baselineImage;
  baselineImage = imageTimeSelector->GetOutput();

  if (m_BaselineStartTimeStep == m_BaselineEndTimeStep)
  {
    this->m_BaselineImage = imageTimeSelector->GetOutput();
  }
  else
  {
    try
    {
      AccessFixedDimensionByItk(this->m_DynamicImage, mitk::ConcentrationCurveGenerator::CalculateAverageBaselineImage, 4);
    }
    catch (itk::ExceptionObject & err)
    {
      std::cerr << "ExceptionObject in ConcentrationCurveGenerator::CalculateAverageBaselineImage caught!" << std::endl;
      std::cerr << err << std::endl;
    }
  }
}

template<class TPixel>
void mitk::ConcentrationCurveGenerator::CalculateAverageBaselineImage(const itk::Image<TPixel, 4> *itkBaselineImage)
{
  if (itkBaselineImage == NULL)
  {
    mitkThrow() << "Error in ConcentrationCurveGenerator::CalculateAverageBaselineImage. Input image is NULL.";
  }
  if (m_BaselineStartTimeStep > m_BaselineEndTimeStep)
  {
    mitkThrow() << "Error in ConcentrationCurveGenerator::CalculateAverageBaselineImage. End time point is before start time point.";
  }

  typedef itk::Image<TPixel, 4> TPixel4DImageType;
  typedef itk::Image<TPixel, 3> TPixel3DImageType;
  typedef itk::Image<double, 3> Double3DImageType;
  typedef itk::Image<double, 4> Double4DImageType;
  typedef itk::ExtractImageFilter<TPixel4DImageType, TPixel4DImageType> ExtractImageFilterType;
  typedef itk::ExtractImageFilter<Double4DImageType, Double3DImageType> Extract3DImageFilterType;
  typedef itk::MeanProjectionImageFilter<TPixel4DImageType,Double4DImageType> MeanProjectionImageFilterType;

  typename MeanProjectionImageFilterType::Pointer MeanProjectionImageFilter = MeanProjectionImageFilterType::New();
  typename Extract3DImageFilterType::Pointer Extract3DImageFilter = Extract3DImageFilterType::New();
  typename TPixel4DImageType::RegionType region_input = itkBaselineImage->GetLargestPossibleRegion();

  if (m_BaselineEndTimeStep > region_input.GetSize()[3])
  {
    mitkThrow() << "Error in ConcentrationCurveGenerator::CalculateAverageBaselineImage. End time point is larger than total number of time points.";
  }

  ExtractImageFilterType::Pointer ExtractFilter = ExtractImageFilterType::New();
  typename TPixel4DImageType::Pointer baselineTimeFrameImage = TPixel4DImageType::New();
  typename TPixel4DImageType::RegionType extractionRegion;
  typename TPixel4DImageType::SizeType size_input_aux = region_input.GetSize();
  size_input_aux[3] = (m_BaselineEndTimeStep - m_BaselineStartTimeStep+1);
  typename TPixel4DImageType::IndexType start_input_aux = region_input.GetIndex();
  start_input_aux[3] = m_BaselineStartTimeStep;
  extractionRegion.SetSize(size_input_aux);
  extractionRegion.SetIndex(start_input_aux);
  ExtractFilter->SetExtractionRegion(extractionRegion);
  ExtractFilter->SetInput(itkBaselineImage);
  ExtractFilter->SetDirectionCollapseToSubmatrix();
  try
  {
    ExtractFilter->Update();
  }
  catch (itk::ExceptionObject & err)
  {
    std::cerr << "ExceptionObject caught!" << std::endl;
    std::cerr << err << std::endl;
  }
  baselineTimeFrameImage = ExtractFilter->GetOutput();
  MeanProjectionImageFilter->SetProjectionDimension(3);
  MeanProjectionImageFilter->SetInput(baselineTimeFrameImage);
  try
  {
    MeanProjectionImageFilter->Update();
  }
  catch (itk::ExceptionObject & err)
  {
    std::cerr << "ExceptionObject caught!" << std::endl;
    std::cerr << err << std::endl;
  }
  Extract3DImageFilter->SetInput(MeanProjectionImageFilter->GetOutput());
  size_input_aux[3] = 0;
  start_input_aux[3] = 0;
  extractionRegion.SetSize(size_input_aux);
  extractionRegion.SetIndex(start_input_aux);
  Extract3DImageFilter->SetExtractionRegion(extractionRegion);
  Extract3DImageFilter->SetDirectionCollapseToSubmatrix();
  try
  {
    Extract3DImageFilter->Update();
  }
  catch (itk::ExceptionObject & err)
  {
    std::cerr << "ExceptionObject caught!" << std::endl;
    std::cerr << err << std::endl;
  }

  Image::Pointer mitkBaselineImage = Image::New();
  CastToMitkImage(Extract3DImageFilter->GetOutput(), mitkBaselineImage);
  this->m_BaselineImage = mitkBaselineImage;
}

mitk::Image::Pointer mitk::ConcentrationCurveGenerator::ConvertSignalToConcentrationCurve(const mitk::Image* inputImage,const mitk::Image* baselineImage)
{
  mitk::PixelType m_PixelType = inputImage->GetPixelType();
  AccessTwoImagesFixedDimensionByItk(inputImage, baselineImage, mitk::ConcentrationCurveGenerator::convertToConcentration, 3);
  return m_ConvertSignalToConcentrationCurve_OutputImage;

}

template<class TPixel_input, class TPixel_baseline>
mitk::Image::Pointer mitk::ConcentrationCurveGenerator::convertToConcentration(const itk::Image<TPixel_input, 3> *itkInputImage, const itk::Image<TPixel_baseline, 3> *itkBaselineImage)
{
    typedef itk::Image<TPixel_input, 3> InputImageType;
    typedef itk::Image<TPixel_baseline, 3> BaselineImageType;
    typedef itk::Image<double, 3> DoubleImageType;

    typename DoubleImageType::Pointer itkDoubleInputImage = DoubleImageType::New();
    typename DoubleImageType::Pointer itkDoubleBaselineImage = DoubleImageType::New();

    typedef itk::CastImageFilter<InputImageType, DoubleImageType> CastInputImageToDoubleImageFilterType;
    typename CastInputImageToDoubleImageFilterType::Pointer CastInputImageToDoubleImageFilter = CastInputImageToDoubleImageFilterType::New();
    CastInputImageToDoubleImageFilter->SetInput(itkInputImage);
    CastInputImageToDoubleImageFilter->Update();
    itkDoubleInputImage = CastInputImageToDoubleImageFilter->GetOutput();

    typedef itk::CastImageFilter<BaselineImageType, DoubleImageType> CastBaselineImageToDoubleImageFilterType;
    typename CastBaselineImageToDoubleImageFilterType::Pointer CastBaselineImageToDoubleImageFilter = CastBaselineImageToDoubleImageFilterType::New();
    CastBaselineImageToDoubleImageFilter->SetInput(itkBaselineImage);
    CastBaselineImageToDoubleImageFilter->Update();
    itkDoubleBaselineImage = CastBaselineImageToDoubleImageFilter->GetOutput();

    if (this->m_isT2weightedImage)
    {
        typedef mitk::ConvertT2ConcentrationFunctor <double, double, double> ConversionFunctorT2Type;
        typedef itk::BinaryFunctorImageFilter<DoubleImageType, DoubleImageType, ConvertedImageType, ConversionFunctorT2Type> FilterT2Type;

        ConversionFunctorT2Type ConversionT2Functor;
        ConversionT2Functor.initialize(this->m_T2Factor, this->m_T2EchoTime);

        typename FilterT2Type::Pointer ConversionT2Filter = FilterT2Type::New();

        ConversionT2Filter->SetFunctor(ConversionT2Functor);
        ConversionT2Filter->SetInput1(itkDoubleInputImage);
        ConversionT2Filter->SetInput2(itkDoubleBaselineImage);

        ConversionT2Filter->Update();

        m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionT2Filter->GetOutput())->Clone();
      }

    else
    {
        if(this->m_isTurboFlashSequence)
        {
            typedef mitk::ConvertToConcentrationTurboFlashFunctor <double, double, double> ConversionFunctorTurboFlashType;
            typedef itk::BinaryFunctorImageFilter<DoubleImageType, DoubleImageType, ConvertedImageType, ConversionFunctorTurboFlashType> FilterTurboFlashType;

            ConversionFunctorTurboFlashType ConversionTurboFlashFunctor;
            ConversionTurboFlashFunctor.initialize(this->m_RelaxationTime, this->m_Relaxivity, this->m_RecoveryTime);

            typename FilterTurboFlashType::Pointer ConversionTurboFlashFilter = FilterTurboFlashType::New();

            ConversionTurboFlashFilter->SetFunctor(ConversionTurboFlashFunctor);
            ConversionTurboFlashFilter->SetInput1(itkDoubleInputImage);
            ConversionTurboFlashFilter->SetInput2(itkDoubleBaselineImage);

            ConversionTurboFlashFilter->Update();
            m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionTurboFlashFilter->GetOutput())->Clone();

        }
        else if(this->m_UsingT1Map)
        {
            typename DoubleImageType::Pointer itkT10Image = DoubleImageType::New();
            mitk::CastToItkImage(m_T10Image, itkT10Image);

            typedef mitk::ConvertToConcentrationViaT1CalcFunctor <double, double, double, double> ConvertToConcentrationViaT1CalcFunctorType;
            typedef itk::TernaryFunctorImageFilter<DoubleImageType, DoubleImageType, DoubleImageType,ConvertedImageType, ConvertToConcentrationViaT1CalcFunctorType> FilterT1MapType;

            ConvertToConcentrationViaT1CalcFunctorType ConversionT1MapFunctor;
            ConversionT1MapFunctor.initialize(this->m_Relaxivity, this->m_RecoveryTime, this->m_FlipAngle);

            typename FilterT1MapType::Pointer ConversionT1MapFilter = FilterT1MapType::New();

            ConversionT1MapFilter->SetFunctor(ConversionT1MapFunctor);
            ConversionT1MapFilter->SetInput1(itkDoubleInputImage);
            ConversionT1MapFilter->SetInput2(itkDoubleBaselineImage);
            ConversionT1MapFilter->SetInput3(itkT10Image);

            ConversionT1MapFilter->Update();
            m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionT1MapFilter->GetOutput())->Clone();

        }

        else if(this->m_AbsoluteSignalEnhancement)
        {
            typedef mitk::ConvertToConcentrationAbsoluteFunctor <double, double, double> ConversionFunctorAbsoluteType;
            typedef itk::BinaryFunctorImageFilter<DoubleImageType, DoubleImageType, ConvertedImageType, ConversionFunctorAbsoluteType> FilterAbsoluteType;

            ConversionFunctorAbsoluteType ConversionAbsoluteFunctor;
            ConversionAbsoluteFunctor.initialize(this->m_Factor);

            typename FilterAbsoluteType::Pointer ConversionAbsoluteFilter = FilterAbsoluteType::New();

            ConversionAbsoluteFilter->SetFunctor(ConversionAbsoluteFunctor);
            ConversionAbsoluteFilter->SetInput1(itkDoubleInputImage);
            ConversionAbsoluteFilter->SetInput2(itkDoubleBaselineImage);

            ConversionAbsoluteFilter->Update();

            m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionAbsoluteFilter->GetOutput())->Clone();
        }

        else if(this->m_RelativeSignalEnhancement)
        {
            typedef mitk::ConvertToConcentrationRelativeFunctor <double, double, double> ConversionFunctorRelativeType;
            typedef itk::BinaryFunctorImageFilter<DoubleImageType, DoubleImageType, ConvertedImageType, ConversionFunctorRelativeType> FilterRelativeType;

            ConversionFunctorRelativeType ConversionRelativeFunctor;
            ConversionRelativeFunctor.initialize(this->m_Factor);

            typename FilterRelativeType::Pointer ConversionRelativeFilter = FilterRelativeType::New();

            ConversionRelativeFilter->SetFunctor(ConversionRelativeFunctor);
            ConversionRelativeFilter->SetInput1(itkDoubleInputImage);
            ConversionRelativeFilter->SetInput2(itkDoubleBaselineImage);

            ConversionRelativeFilter->Update();

            m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionRelativeFilter->GetOutput())->Clone();
        }

    }
    return m_ConvertSignalToConcentrationCurve_OutputImage;

}

<|endoftext|>


<commit_before>// Copyright (c) 2009 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 "chrome/browser/chromeos/main_menu.h"

#include <vector>

#include "app/gfx/insets.h"
#include "app/resource_bundle.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_view_host_factory.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "views/background.h"
#include "views/painter.h"
#include "views/screen.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_gtk.h"

// Initial size of the renderer. This is contained within a window whose size
// is set to the size of the image IDR_MAIN_MENU_BUTTON_DROP_DOWN.
static const int kRendererX = 0;
static const int kRendererY = 25;
static const int kRendererWidth = 250;
static const int kRendererHeight = 400;

// Insets defining the regions that are stretched and titled to create the
// background of the popup. These constants are fed into
// Painter::CreateImagePainter as the insets, see it for details.
static const int kBackgroundImageTop = 27;
static const int kBackgroundImageLeft = 85;
static const int kBackgroundImageBottom = 10;
static const int kBackgroundImageRight = 8;

// Command line switch for specifying url of the page.
static const wchar_t kURLSwitch[] = L"main-menu-url";

// Command line switch for specifying the size of the main menu. The default is
// full screen.
static const wchar_t kMenuSizeSwitch[] = L"main-menu-size";

// URL of the page to load. This is ignored if kURLSwitch is specified.
static const char kMenuURL[] = "http://goto.ext.google.com/crux-menu";

// Returns the size of the popup. By default the popup is sized slightly
// larger than full screen, but can be overriden by the command line switch
// kMenuSizeSwitch.
static gfx::Size GetPopupSize() {
  std::wstring cl_size =
      CommandLine::ForCurrentProcess()->GetSwitchValue(kMenuSizeSwitch);
  if (!cl_size.empty()) {
    std::vector<std::string> chunks;
    SplitString(WideToUTF8(cl_size), 'x', &chunks);
    if (chunks.size() == 2)
      return gfx::Size(StringToInt(chunks[0]), StringToInt(chunks[1]));
  }

  gfx::Size size =
      views::Screen::GetMonitorAreaNearestPoint(gfx::Point(0, 0)).size();
  // When full screen we don't want to see the drop shadow. Adjust the width
  // so the drop shadow ends up off screen.
  size.Enlarge(kBackgroundImageRight, kBackgroundImageBottom);
  return size;
}

// Returns the size for the renderer widget host view given the specified
// size of the popup.
static gfx::Size CalculateRWHVSize(const gfx::Size& popup_size) {
  return gfx::Size(popup_size.width() - kRendererX - kBackgroundImageRight,
                   popup_size.height() - kRendererY - kBackgroundImageBottom);
}

// Returns the URL of the menu.
static GURL GetMenuURL() {
  std::wstring url_string =
      CommandLine::ForCurrentProcess()->GetSwitchValue(kURLSwitch);
  if (!url_string.empty())
    return GURL(WideToUTF8(url_string));
  return GURL(kMenuURL);
}

// static
void MainMenu::Show(Browser* browser) {
  (new MainMenu(browser))->ShowImpl();
}

MainMenu::~MainMenu() {
  popup_->Close();
  menu_rvh_->Shutdown();
}

MainMenu::MainMenu(Browser* browser)
    : browser_(browser),
      popup_(NULL),
      site_instance_(NULL),
      menu_rvh_(NULL),
      rwhv_(NULL),
      ALLOW_THIS_IN_INITIALIZER_LIST(tab_contents_delegate_(this)) {
}

void MainMenu::ShowImpl() {
  SkBitmap* drop_down_image = ResourceBundle::GetSharedInstance().
      GetBitmapNamed(IDR_MAIN_MENU_BUTTON_DROP_DOWN);

  views::WidgetGtk* menu_popup =
      new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP);
  popup_ = menu_popup;
  // The background image has transparency, so we make the window transparent.
  menu_popup->MakeTransparent();
  gfx::Size popup_size = GetPopupSize();
  menu_popup->Init(NULL, gfx::Rect(0, 0, popup_size.width(),
                                   popup_size.height()));

  views::Painter* painter = views::Painter::CreateImagePainter(
      *drop_down_image,
      gfx::Insets(kBackgroundImageTop, kBackgroundImageLeft,
                  kBackgroundImageBottom, kBackgroundImageRight));
  menu_popup->GetRootView()->set_background(
      views::Background::CreateBackgroundPainter(true, painter));

  GURL menu_url(GetMenuURL());
  site_instance_ = SiteInstance::CreateSiteInstanceForURL(browser_->profile(),
                                                          menu_url);
  menu_rvh_ = new RenderViewHost(site_instance_, this, MSG_ROUTING_NONE);

  rwhv_ = new RenderWidgetHostViewGtk(menu_rvh_);
  rwhv_->InitAsChild();
  menu_rvh_->CreateRenderView();
  menu_popup->AddChild(rwhv_->GetNativeView());
  gfx::Size rwhv_size = CalculateRWHVSize(popup_size);
  menu_popup->PositionChild(rwhv_->GetNativeView(), kRendererX, kRendererY,
                            rwhv_size.width(), rwhv_size.height());
  rwhv_->SetSize(rwhv_size);
  menu_rvh_->NavigateToURL(menu_url);
  menu_popup->Show();

  GtkWidget* rwhv_widget = rwhv_->GetNativeView();
  gtk_widget_realize(rwhv_widget);
  g_signal_connect(rwhv_widget, "button-press-event",
                   G_CALLBACK(CallButtonPressEvent), this);
  // Do a mouse grab on the renderer widget host view's widget so that we can
  // close the popup if the user clicks anywhere else. And do a keyboard
  // grab so that we get all key events.
  gdk_pointer_grab(rwhv_widget->window, FALSE,
                   static_cast<GdkEventMask>(
                         GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
                         GDK_POINTER_MOTION_MASK),
                   NULL, NULL, GDK_CURRENT_TIME);
  gdk_keyboard_grab(rwhv_widget->window, FALSE, GDK_CURRENT_TIME);
}

void MainMenu::Delete(bool now) {
  gdk_keyboard_ungrab(GDK_CURRENT_TIME);
  gdk_pointer_ungrab(GDK_CURRENT_TIME);
  // Hide the popup immediately. We don't close it as it contains the
  // renderwidgethostview, which hasn't been shutdown yet.
  popup_->Hide();
  if (now)
    delete this;
  else
    MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}

// static
gboolean MainMenu::CallButtonPressEvent(GtkWidget* widget,
                                        GdkEventButton* event,
                                        MainMenu* menu) {
  return menu->OnButtonPressEvent(widget, event);
}

gboolean MainMenu::OnButtonPressEvent(GtkWidget* widget,
                                      GdkEventButton* event) {
  if (event->x < 0 || event->y < 0 ||
      event->x >= widget->allocation.width ||
      event->y >= widget->allocation.height) {
    // The user clicked outside the bounds of the menu, delete the main which
    // results in closing it.
    Delete(true);
  }
  return FALSE;
}

void MainMenu::RequestMove(const gfx::Rect& new_bounds) {
  // Invoking PositionChild results in a gtk signal that triggers attempting to
  // to resize the window. We need to set the size request so that it resizes
  // correctly when this happens.
  gtk_widget_set_size_request(popup_->GetNativeView(),
                              new_bounds.width(), new_bounds.height());
  gfx::Size rwhv_size = CalculateRWHVSize(new_bounds.size());
  popup_->PositionChild(rwhv_->GetNativeView(), kRendererX, kRendererY,
                        rwhv_size.width(), rwhv_size.height());
  popup_->SetBounds(new_bounds);
  rwhv_->SetSize(rwhv_size);
}

void MainMenu::CreateNewWindow(int route_id) {
  if (pending_contents_.get()) {
    NOTREACHED();
    return;
  }

  helper_.CreateNewWindow(route_id, browser_->profile(), site_instance_,
                          DOMUIFactory::GetDOMUIType(GURL(GetMenuURL())),
                          NULL);
  pending_contents_.reset(helper_.GetCreatedWindow(route_id));
  pending_contents_->set_delegate(&tab_contents_delegate_);
}

void MainMenu::ShowCreatedWindow(int route_id,
                                 WindowOpenDisposition disposition,
                                 const gfx::Rect& initial_pos,
                                 bool user_gesture,
                                 const GURL& creator_url) {
  if (disposition == NEW_POPUP) {
    pending_contents_->set_delegate(NULL);
    browser_->GetSelectedTabContents()->AddNewContents(
        pending_contents_.release(), disposition, initial_pos, user_gesture,
        creator_url);
    Delete(false);
  }
}

void MainMenu::TabContentsDelegateImpl::OpenURLFromTab(
    TabContents* source,
    const GURL& url,
    const GURL& referrer,
    WindowOpenDisposition disposition,
    PageTransition::Type transition) {
  menu_->browser_->OpenURL(url, referrer, NEW_FOREGROUND_TAB,
                           PageTransition::LINK);
  menu_->Delete(true);
}
<commit_msg>Changes the url of the main menu.<commit_after>// Copyright (c) 2009 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 "chrome/browser/chromeos/main_menu.h"

#include <vector>

#include "app/gfx/insets.h"
#include "app/resource_bundle.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_view_host_factory.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "views/background.h"
#include "views/painter.h"
#include "views/screen.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_gtk.h"

// Initial size of the renderer. This is contained within a window whose size
// is set to the size of the image IDR_MAIN_MENU_BUTTON_DROP_DOWN.
static const int kRendererX = 0;
static const int kRendererY = 25;
static const int kRendererWidth = 250;
static const int kRendererHeight = 400;

// Insets defining the regions that are stretched and titled to create the
// background of the popup. These constants are fed into
// Painter::CreateImagePainter as the insets, see it for details.
static const int kBackgroundImageTop = 27;
static const int kBackgroundImageLeft = 85;
static const int kBackgroundImageBottom = 10;
static const int kBackgroundImageRight = 8;

// Command line switch for specifying url of the page.
static const wchar_t kURLSwitch[] = L"main-menu-url";

// Command line switch for specifying the size of the main menu. The default is
// full screen.
static const wchar_t kMenuSizeSwitch[] = L"main-menu-size";

// URL of the page to load. This is ignored if kURLSwitch is specified.
static const char kMenuURL[] = "http://goto.ext.google.com/crux-home";

// Returns the size of the popup. By default the popup is sized slightly
// larger than full screen, but can be overriden by the command line switch
// kMenuSizeSwitch.
static gfx::Size GetPopupSize() {
  std::wstring cl_size =
      CommandLine::ForCurrentProcess()->GetSwitchValue(kMenuSizeSwitch);
  if (!cl_size.empty()) {
    std::vector<std::string> chunks;
    SplitString(WideToUTF8(cl_size), 'x', &chunks);
    if (chunks.size() == 2)
      return gfx::Size(StringToInt(chunks[0]), StringToInt(chunks[1]));
  }

  gfx::Size size =
      views::Screen::GetMonitorAreaNearestPoint(gfx::Point(0, 0)).size();
  // When full screen we don't want to see the drop shadow. Adjust the width
  // so the drop shadow ends up off screen.
  size.Enlarge(kBackgroundImageRight, kBackgroundImageBottom);
  return size;
}

// Returns the size for the renderer widget host view given the specified
// size of the popup.
static gfx::Size CalculateRWHVSize(const gfx::Size& popup_size) {
  return gfx::Size(popup_size.width() - kRendererX - kBackgroundImageRight,
                   popup_size.height() - kRendererY - kBackgroundImageBottom);
}

// Returns the URL of the menu.
static GURL GetMenuURL() {
  std::wstring url_string =
      CommandLine::ForCurrentProcess()->GetSwitchValue(kURLSwitch);
  if (!url_string.empty())
    return GURL(WideToUTF8(url_string));
  return GURL(kMenuURL);
}

// static
void MainMenu::Show(Browser* browser) {
  (new MainMenu(browser))->ShowImpl();
}

MainMenu::~MainMenu() {
  popup_->Close();
  menu_rvh_->Shutdown();
}

MainMenu::MainMenu(Browser* browser)
    : browser_(browser),
      popup_(NULL),
      site_instance_(NULL),
      menu_rvh_(NULL),
      rwhv_(NULL),
      ALLOW_THIS_IN_INITIALIZER_LIST(tab_contents_delegate_(this)) {
}

void MainMenu::ShowImpl() {
  SkBitmap* drop_down_image = ResourceBundle::GetSharedInstance().
      GetBitmapNamed(IDR_MAIN_MENU_BUTTON_DROP_DOWN);

  views::WidgetGtk* menu_popup =
      new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP);
  popup_ = menu_popup;
  // The background image has transparency, so we make the window transparent.
  menu_popup->MakeTransparent();
  gfx::Size popup_size = GetPopupSize();
  menu_popup->Init(NULL, gfx::Rect(0, 0, popup_size.width(),
                                   popup_size.height()));

  views::Painter* painter = views::Painter::CreateImagePainter(
      *drop_down_image,
      gfx::Insets(kBackgroundImageTop, kBackgroundImageLeft,
                  kBackgroundImageBottom, kBackgroundImageRight));
  menu_popup->GetRootView()->set_background(
      views::Background::CreateBackgroundPainter(true, painter));

  GURL menu_url(GetMenuURL());
  site_instance_ = SiteInstance::CreateSiteInstanceForURL(browser_->profile(),
                                                          menu_url);
  menu_rvh_ = new RenderViewHost(site_instance_, this, MSG_ROUTING_NONE);

  rwhv_ = new RenderWidgetHostViewGtk(menu_rvh_);
  rwhv_->InitAsChild();
  menu_rvh_->CreateRenderView();
  menu_popup->AddChild(rwhv_->GetNativeView());
  gfx::Size rwhv_size = CalculateRWHVSize(popup_size);
  menu_popup->PositionChild(rwhv_->GetNativeView(), kRendererX, kRendererY,
                            rwhv_size.width(), rwhv_size.height());
  rwhv_->SetSize(rwhv_size);
  menu_rvh_->NavigateToURL(menu_url);
  menu_popup->Show();

  GtkWidget* rwhv_widget = rwhv_->GetNativeView();
  gtk_widget_realize(rwhv_widget);
  g_signal_connect(rwhv_widget, "button-press-event",
                   G_CALLBACK(CallButtonPressEvent), this);
  // Do a mouse grab on the renderer widget host view's widget so that we can
  // close the popup if the user clicks anywhere else. And do a keyboard
  // grab so that we get all key events.
  gdk_pointer_grab(rwhv_widget->window, FALSE,
                   static_cast<GdkEventMask>(
                         GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
                         GDK_POINTER_MOTION_MASK),
                   NULL, NULL, GDK_CURRENT_TIME);
  gdk_keyboard_grab(rwhv_widget->window, FALSE, GDK_CURRENT_TIME);
}

void MainMenu::Delete(bool now) {
  gdk_keyboard_ungrab(GDK_CURRENT_TIME);
  gdk_pointer_ungrab(GDK_CURRENT_TIME);
  // Hide the popup immediately. We don't close it as it contains the
  // renderwidgethostview, which hasn't been shutdown yet.
  popup_->Hide();
  if (now)
    delete this;
  else
    MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}

// static
gboolean MainMenu::CallButtonPressEvent(GtkWidget* widget,
                                        GdkEventButton* event,
                                        MainMenu* menu) {
  return menu->OnButtonPressEvent(widget, event);
}

gboolean MainMenu::OnButtonPressEvent(GtkWidget* widget,
                                      GdkEventButton* event) {
  if (event->x < 0 || event->y < 0 ||
      event->x >= widget->allocation.width ||
      event->y >= widget->allocation.height) {
    // The user clicked outside the bounds of the menu, delete the main which
    // results in closing it.
    Delete(true);
  }
  return FALSE;
}

void MainMenu::RequestMove(const gfx::Rect& new_bounds) {
  // Invoking PositionChild results in a gtk signal that triggers attempting to
  // to resize the window. We need to set the size request so that it resizes
  // correctly when this happens.
  gtk_widget_set_size_request(popup_->GetNativeView(),
                              new_bounds.width(), new_bounds.height());
  gfx::Size rwhv_size = CalculateRWHVSize(new_bounds.size());
  popup_->PositionChild(rwhv_->GetNativeView(), kRendererX, kRendererY,
                        rwhv_size.width(), rwhv_size.height());
  popup_->SetBounds(new_bounds);
  rwhv_->SetSize(rwhv_size);
}

void MainMenu::CreateNewWindow(int route_id) {
  if (pending_contents_.get()) {
    NOTREACHED();
    return;
  }

  helper_.CreateNewWindow(route_id, browser_->profile(), site_instance_,
                          DOMUIFactory::GetDOMUIType(GURL(GetMenuURL())),
                          NULL);
  pending_contents_.reset(helper_.GetCreatedWindow(route_id));
  pending_contents_->set_delegate(&tab_contents_delegate_);
}

void MainMenu::ShowCreatedWindow(int route_id,
                                 WindowOpenDisposition disposition,
                                 const gfx::Rect& initial_pos,
                                 bool user_gesture,
                                 const GURL& creator_url) {
  if (disposition == NEW_POPUP) {
    pending_contents_->set_delegate(NULL);
    browser_->GetSelectedTabContents()->AddNewContents(
        pending_contents_.release(), disposition, initial_pos, user_gesture,
        creator_url);
    Delete(false);
  }
}

void MainMenu::TabContentsDelegateImpl::OpenURLFromTab(
    TabContents* source,
    const GURL& url,
    const GURL& referrer,
    WindowOpenDisposition disposition,
    PageTransition::Type transition) {
  menu_->browser_->OpenURL(url, referrer, NEW_FOREGROUND_TAB,
                           PageTransition::LINK);
  menu_->Delete(true);
}
<|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 "chrome/browser/file_select_helper.h"

#include <string>

#include "base/file_util.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "net/base/mime_util.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/shell_dialogs.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/render_messages_params.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

FileSelectHelper::FileSelectHelper(Profile* profile)
    : profile_(profile),
      render_view_host_(NULL),
      select_file_dialog_(),
      dialog_type_(SelectFileDialog::SELECT_OPEN_FILE) {
}

FileSelectHelper::~FileSelectHelper() {
  // There may be pending file dialogs, we need to tell them that we've gone
  // away so they don't try and call back to us.
  if (select_file_dialog_.get())
    select_file_dialog_->ListenerDestroyed();

  // Stop any pending directory enumeration and prevent a callback.
  if (directory_lister_.get()) {
    directory_lister_->set_delegate(NULL);
    directory_lister_->Cancel();
  }
}

void FileSelectHelper::FileSelected(const FilePath& path,
                                    int index, void* params) {
  if (!render_view_host_)
    return;

  profile_->set_last_selected_directory(path.DirName());

  if (dialog_type_ == SelectFileDialog::SELECT_FOLDER) {
    DirectorySelected(path);
    return;
  }

  std::vector<FilePath> files;
  files.push_back(path);
  render_view_host_->FilesSelectedInChooser(files);
  // We are done with this showing of the dialog.
  render_view_host_ = NULL;
}

void FileSelectHelper::MultiFilesSelected(const std::vector<FilePath>& files,
                                          void* params) {
  if (!files.empty())
    profile_->set_last_selected_directory(files[0].DirName());
  if (!render_view_host_)
    return;

  render_view_host_->FilesSelectedInChooser(files);
  // We are done with this showing of the dialog.
  render_view_host_ = NULL;
}

void FileSelectHelper::FileSelectionCanceled(void* params) {
  if (!render_view_host_)
    return;

  // If the user cancels choosing a file to upload we pass back an
  // empty vector.
  render_view_host_->FilesSelectedInChooser(std::vector<FilePath>());

  // We are done with this showing of the dialog.
  render_view_host_ = NULL;
}

void FileSelectHelper::DirectorySelected(const FilePath& path) {
  directory_lister_ = new net::DirectoryLister(path,
                                               true,
                                               net::DirectoryLister::NO_SORT,
                                               this);
  if (!directory_lister_->Start())
    FileSelectionCanceled(NULL);
}

void FileSelectHelper::OnListFile(
    const net::DirectoryLister::DirectoryListerData& data) {
  // Directory upload only cares about files.  This util call just checks
  // the flags in the structure; there's no file I/O going on.
  if (file_util::FileEnumerator::IsDirectory(data.info))
    return;

  directory_lister_results_.push_back(data.path);
}

void FileSelectHelper::OnListDone(int error) {
  if (!render_view_host_)
    return;

  if (error) {
    FileSelectionCanceled(NULL);
    return;
  }

  render_view_host_->FilesSelectedInChooser(directory_lister_results_);
  render_view_host_ = NULL;
  directory_lister_ = NULL;
  directory_lister_results_.clear();
}

SelectFileDialog::FileTypeInfo* FileSelectHelper::GetFileTypesFromAcceptType(
    const string16& accept_types) {
  if (accept_types.empty())
    return NULL;

  // Split the accept-type string on commas.
  std::vector<string16> mime_types;
  base::SplitStringUsingSubstr(accept_types, ASCIIToUTF16(","), &mime_types);
  if (mime_types.empty())
    return NULL;

  // Create FileTypeInfo and pre-allocate for the first extension list.
  scoped_ptr<SelectFileDialog::FileTypeInfo> file_type(
      new SelectFileDialog::FileTypeInfo());
  file_type->include_all_files = true;
  file_type->extensions.resize(1);
  std::vector<FilePath::StringType>* extensions = &file_type->extensions.back();

  // Find the correspondinge extensions.
  int valid_type_count = 0;
  int description_id = 0;
  for (size_t i = 0; i < mime_types.size(); ++i) {
    string16 mime_type = mime_types[i];
    std::string ascii_mime_type = StringToLowerASCII(UTF16ToASCII(mime_type));

    TrimWhitespace(ascii_mime_type, TRIM_ALL, &ascii_mime_type);
    if (ascii_mime_type.empty())
      continue;

    size_t old_extension_size = extensions->size();
    if (ascii_mime_type == "image/*") {
      description_id = IDS_IMAGE_FILES;
      net::GetImageExtensions(extensions);
    } else if (ascii_mime_type == "audio/*") {
      description_id = IDS_AUDIO_FILES;
      net::GetAudioExtensions(extensions);
    } else if (ascii_mime_type == "video/*") {
      description_id = IDS_VIDEO_FILES;
      net::GetVideoExtensions(extensions);
    } else {
      net::GetExtensionsForMimeType(ascii_mime_type, extensions);
    }

    if (extensions->size() > old_extension_size)
      valid_type_count++;
  }

  // If no valid extension is added, bail out.
  if (valid_type_count == 0)
    return NULL;

  // Use a generic description "Custom Files" if either of the following is
  // true:
  // 1) There're multiple types specified, like "audio/*,video/*"
  // 2) There're multiple extensions for a MIME type without parameter, like
  //    "ehtml,shtml,htm,html" for "text/html". On Windows, the select file
  //    dialog uses the first extension in the list to form the description,
  //    like "EHTML Files". This is not what we want.
  if (valid_type_count > 1 ||
      (valid_type_count == 1 && description_id == 0 && extensions->size() > 1))
    description_id = IDS_CUSTOM_FILES;

  if (description_id) {
    file_type->extension_description_overrides.push_back(
        l10n_util::GetStringUTF16(description_id));
  }

  return file_type.release();
}

void FileSelectHelper::RunFileChooser(
    RenderViewHost* render_view_host,
    const ViewHostMsg_RunFileChooser_Params &params) {
  DCHECK(!render_view_host_);
  render_view_host_ = render_view_host;
  notification_registrar_.RemoveAll();
  notification_registrar_.Add(this,
                              NotificationType::RENDER_WIDGET_HOST_DESTROYED,
                              Source<RenderViewHost>(render_view_host));

  if (!select_file_dialog_.get())
    select_file_dialog_ = SelectFileDialog::Create(this);

  switch (params.mode) {
    case ViewHostMsg_RunFileChooser_Params::Open:
      dialog_type_ = SelectFileDialog::SELECT_OPEN_FILE;
      break;
    case ViewHostMsg_RunFileChooser_Params::OpenMultiple:
      dialog_type_ = SelectFileDialog::SELECT_OPEN_MULTI_FILE;
      break;
    case ViewHostMsg_RunFileChooser_Params::OpenFolder:
      dialog_type_ = SelectFileDialog::SELECT_FOLDER;
      break;
    case ViewHostMsg_RunFileChooser_Params::Save:
      dialog_type_ = SelectFileDialog::SELECT_SAVEAS_FILE;
      break;
    default:
      dialog_type_ = SelectFileDialog::SELECT_OPEN_FILE;  // Prevent warning.
      NOTREACHED();
  }
  scoped_ptr<SelectFileDialog::FileTypeInfo> file_types(
      GetFileTypesFromAcceptType(params.accept_types));
  FilePath default_file_name = params.default_file_name;
  if (default_file_name.empty())
    default_file_name = profile_->last_selected_directory();

  gfx::NativeWindow owning_window =
      platform_util::GetTopLevel(render_view_host_->view()->GetNativeView());
  select_file_dialog_->SelectFile(dialog_type_,
                                  params.title,
                                  default_file_name,
                                  file_types.get(),
                                  file_types.get() ? 1 : 0,  // 1-based index.
                                  FILE_PATH_LITERAL(""),
                                  owning_window,
                                  NULL);
}

void FileSelectHelper::Observe(NotificationType type,
                               const NotificationSource& source,
                               const NotificationDetails& details) {
  DCHECK(type == NotificationType::RENDER_WIDGET_HOST_DESTROYED);
  DCHECK(Details<RenderViewHost>(details).ptr() == render_view_host_);
  render_view_host_ = NULL;
}
<commit_msg>For directory upload, show empty directories (all directories, in fact) by including the corresponding "." file in the result set.<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 "chrome/browser/file_select_helper.h"

#include <string>

#include "base/file_util.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "net/base/mime_util.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/shell_dialogs.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/render_messages_params.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

FileSelectHelper::FileSelectHelper(Profile* profile)
    : profile_(profile),
      render_view_host_(NULL),
      select_file_dialog_(),
      dialog_type_(SelectFileDialog::SELECT_OPEN_FILE) {
}

FileSelectHelper::~FileSelectHelper() {
  // There may be pending file dialogs, we need to tell them that we've gone
  // away so they don't try and call back to us.
  if (select_file_dialog_.get())
    select_file_dialog_->ListenerDestroyed();

  // Stop any pending directory enumeration and prevent a callback.
  if (directory_lister_.get()) {
    directory_lister_->set_delegate(NULL);
    directory_lister_->Cancel();
  }
}

void FileSelectHelper::FileSelected(const FilePath& path,
                                    int index, void* params) {
  if (!render_view_host_)
    return;

  profile_->set_last_selected_directory(path.DirName());

  if (dialog_type_ == SelectFileDialog::SELECT_FOLDER) {
    DirectorySelected(path);
    return;
  }

  std::vector<FilePath> files;
  files.push_back(path);
  render_view_host_->FilesSelectedInChooser(files);
  // We are done with this showing of the dialog.
  render_view_host_ = NULL;
}

void FileSelectHelper::MultiFilesSelected(const std::vector<FilePath>& files,
                                          void* params) {
  if (!files.empty())
    profile_->set_last_selected_directory(files[0].DirName());
  if (!render_view_host_)
    return;

  render_view_host_->FilesSelectedInChooser(files);
  // We are done with this showing of the dialog.
  render_view_host_ = NULL;
}

void FileSelectHelper::FileSelectionCanceled(void* params) {
  if (!render_view_host_)
    return;

  // If the user cancels choosing a file to upload we pass back an
  // empty vector.
  render_view_host_->FilesSelectedInChooser(std::vector<FilePath>());

  // We are done with this showing of the dialog.
  render_view_host_ = NULL;
}

void FileSelectHelper::DirectorySelected(const FilePath& path) {
  directory_lister_ = new net::DirectoryLister(path,
                                               true,
                                               net::DirectoryLister::NO_SORT,
                                               this);
  if (!directory_lister_->Start())
    FileSelectionCanceled(NULL);
}

void FileSelectHelper::OnListFile(
    const net::DirectoryLister::DirectoryListerData& data) {
  // Directory upload returns directories via a "." file, so that
  // empty directories are included.  This util call just checks
  // the flags in the structure; there's no file I/O going on.
  if (file_util::FileEnumerator::IsDirectory(data.info))
    directory_lister_results_.push_back(
        data.path.Append(FILE_PATH_LITERAL(".")));
  else
    directory_lister_results_.push_back(data.path);
}

void FileSelectHelper::OnListDone(int error) {
  if (!render_view_host_)
    return;

  if (error) {
    FileSelectionCanceled(NULL);
    return;
  }

  render_view_host_->FilesSelectedInChooser(directory_lister_results_);
  render_view_host_ = NULL;
  directory_lister_ = NULL;
  directory_lister_results_.clear();
}

SelectFileDialog::FileTypeInfo* FileSelectHelper::GetFileTypesFromAcceptType(
    const string16& accept_types) {
  if (accept_types.empty())
    return NULL;

  // Split the accept-type string on commas.
  std::vector<string16> mime_types;
  base::SplitStringUsingSubstr(accept_types, ASCIIToUTF16(","), &mime_types);
  if (mime_types.empty())
    return NULL;

  // Create FileTypeInfo and pre-allocate for the first extension list.
  scoped_ptr<SelectFileDialog::FileTypeInfo> file_type(
      new SelectFileDialog::FileTypeInfo());
  file_type->include_all_files = true;
  file_type->extensions.resize(1);
  std::vector<FilePath::StringType>* extensions = &file_type->extensions.back();

  // Find the correspondinge extensions.
  int valid_type_count = 0;
  int description_id = 0;
  for (size_t i = 0; i < mime_types.size(); ++i) {
    string16 mime_type = mime_types[i];
    std::string ascii_mime_type = StringToLowerASCII(UTF16ToASCII(mime_type));

    TrimWhitespace(ascii_mime_type, TRIM_ALL, &ascii_mime_type);
    if (ascii_mime_type.empty())
      continue;

    size_t old_extension_size = extensions->size();
    if (ascii_mime_type == "image/*") {
      description_id = IDS_IMAGE_FILES;
      net::GetImageExtensions(extensions);
    } else if (ascii_mime_type == "audio/*") {
      description_id = IDS_AUDIO_FILES;
      net::GetAudioExtensions(extensions);
    } else if (ascii_mime_type == "video/*") {
      description_id = IDS_VIDEO_FILES;
      net::GetVideoExtensions(extensions);
    } else {
      net::GetExtensionsForMimeType(ascii_mime_type, extensions);
    }

    if (extensions->size() > old_extension_size)
      valid_type_count++;
  }

  // If no valid extension is added, bail out.
  if (valid_type_count == 0)
    return NULL;

  // Use a generic description "Custom Files" if either of the following is
  // true:
  // 1) There're multiple types specified, like "audio/*,video/*"
  // 2) There're multiple extensions for a MIME type without parameter, like
  //    "ehtml,shtml,htm,html" for "text/html". On Windows, the select file
  //    dialog uses the first extension in the list to form the description,
  //    like "EHTML Files". This is not what we want.
  if (valid_type_count > 1 ||
      (valid_type_count == 1 && description_id == 0 && extensions->size() > 1))
    description_id = IDS_CUSTOM_FILES;

  if (description_id) {
    file_type->extension_description_overrides.push_back(
        l10n_util::GetStringUTF16(description_id));
  }

  return file_type.release();
}

void FileSelectHelper::RunFileChooser(
    RenderViewHost* render_view_host,
    const ViewHostMsg_RunFileChooser_Params &params) {
  DCHECK(!render_view_host_);
  render_view_host_ = render_view_host;
  notification_registrar_.RemoveAll();
  notification_registrar_.Add(this,
                              NotificationType::RENDER_WIDGET_HOST_DESTROYED,
                              Source<RenderViewHost>(render_view_host));

  if (!select_file_dialog_.get())
    select_file_dialog_ = SelectFileDialog::Create(this);

  switch (params.mode) {
    case ViewHostMsg_RunFileChooser_Params::Open:
      dialog_type_ = SelectFileDialog::SELECT_OPEN_FILE;
      break;
    case ViewHostMsg_RunFileChooser_Params::OpenMultiple:
      dialog_type_ = SelectFileDialog::SELECT_OPEN_MULTI_FILE;
      break;
    case ViewHostMsg_RunFileChooser_Params::OpenFolder:
      dialog_type_ = SelectFileDialog::SELECT_FOLDER;
      break;
    case ViewHostMsg_RunFileChooser_Params::Save:
      dialog_type_ = SelectFileDialog::SELECT_SAVEAS_FILE;
      break;
    default:
      dialog_type_ = SelectFileDialog::SELECT_OPEN_FILE;  // Prevent warning.
      NOTREACHED();
  }
  scoped_ptr<SelectFileDialog::FileTypeInfo> file_types(
      GetFileTypesFromAcceptType(params.accept_types));
  FilePath default_file_name = params.default_file_name;
  if (default_file_name.empty())
    default_file_name = profile_->last_selected_directory();

  gfx::NativeWindow owning_window =
      platform_util::GetTopLevel(render_view_host_->view()->GetNativeView());
  select_file_dialog_->SelectFile(dialog_type_,
                                  params.title,
                                  default_file_name,
                                  file_types.get(),
                                  file_types.get() ? 1 : 0,  // 1-based index.
                                  FILE_PATH_LITERAL(""),
                                  owning_window,
                                  NULL);
}

void FileSelectHelper::Observe(NotificationType type,
                               const NotificationSource& source,
                               const NotificationDetails& details) {
  DCHECK(type == NotificationType::RENDER_WIDGET_HOST_DESTROYED);
  DCHECK(Details<RenderViewHost>(details).ptr() == render_view_host_);
  render_view_host_ = NULL;
}
<|endoftext|>


<commit_before>#include "ospray/common/OSPCommon.h"
#include "ospray/common/Thread.h"
#include "common/sys/sync/barrier.h"

namespace ospray {

  using namespace std;

  volatile size_t sum = 0;
  volatile int nextFreeID = 0;
  volatile bool done = 0;
  double timeToRun = 1.f;
  embree::MutexSys mutex;
  embree::BarrierSys barrier;

  struct MyThread : public Thread {
    MyThread(int numThreads)
    {
    }

    virtual void run()
    {
      mutex.lock();
      int myID = nextFreeID++;
      mutex.unlock();

      barrier.wait();
      double t0 = getSysTime();
      int lastPing = 0;
      while (1) {
        barrier.wait();
        if (done) {
          break;
        }
        mutex.lock();
        sum += 1;
        mutex.unlock();
        barrier.wait();

        double t1 = getSysTime();

        if (myID == 0) {
          int numSecs = int(t1-t0);
          if (numSecs > lastPing) {
            printf("after t=%5.fs: num ops =%8li, that's %f ops/sec\n",
                   t1-t0,sum,sum/(t1-t0));
            lastPing = numSecs;
          }
        }
        if (myID == 0 && (t1 - t0) >= timeToRun)
          done = true;
      }

      if (myID == 0)
        cout << "total number of OPs: " << sum << endl;
    }

  };

  int numThreads = 10;
  int firstThreadID = 1;

  extern "C" int main(int ac, char **av)
  {
    for (int i=1;i<ac;i++) {
      const std::string arg = av[i];
      if (arg == "-nt")
        numThreads = atoi(av[++i]);
      else if (arg == "-ft")
        firstThreadID = atoi(av[++i]);
      else if (arg == "-ns")
        timeToRun = atof(av[++i]);
      else
        throw std::runtime_error("unknown parameter '"+arg+"'");
    }

    barrier.init(numThreads);
    MyThread **thread = new MyThread *[numThreads];
    for (int i=0;i<numThreads;i++) {
      thread[i] = new MyThread(numThreads);
      thread[i]->start(firstThreadID+i);
    }

    while (1) {
      sleep(1);
      if (done) break;
    }

    for (int i=0;i<numThreads;i++)
      thread[i]->join();
    return 0;
  }

}
<commit_msg>printing addr and thread id of main<commit_after>#include "ospray/common/OSPCommon.h"
#include "ospray/common/Thread.h"
#include "common/sys/sync/barrier.h"
#include <sched.h>

namespace ospray {

  using namespace std;

  volatile size_t sum = 0;
  volatile int nextFreeID = 0;
  volatile bool done = 0;
  double timeToRun = 1.f;
  embree::MutexSys mutex;
  embree::BarrierSys barrier;

  struct MyThread : public Thread {
    MyThread(int numThreads)
    {
    }

    virtual void run()
    {
      mutex.lock();
      int myID = nextFreeID++;
      mutex.unlock();

      barrier.wait();
      double t0 = getSysTime();
      int lastPing = 0;
      while (1) {
        barrier.wait();
        if (done) {
          break;
        }
        mutex.lock();
        sum += 1;
        mutex.unlock();
        barrier.wait();

        double t1 = getSysTime();

        if (myID == 0) {
          int numSecs = int(t1-t0);
          if (numSecs > lastPing) {
            printf("after t=%5.fs: num ops =%8li, that's %f ops/sec\n",
                   t1-t0,sum,sum/(t1-t0));
            lastPing = numSecs;
          }
        }
        if (myID == 0 && (t1 - t0) >= timeToRun)
          done = true;
      }

      if (myID == 0)
        cout << "total number of OPs: " << sum << endl;
    }

  };

  int numThreads = 10;
  int firstThreadID = 1;

  extern "C" int main(int ac, char **av)
  {
#ifdef __LINUX__
    printf("main thread runs on core %i\n",sched_getcpu());
#endif
    printf("address of global variables is %li\n",(long)&sum);

    for (int i=1;i<ac;i++) {
      const std::string arg = av[i];
      if (arg == "-nt")
        numThreads = atoi(av[++i]);
      else if (arg == "-ft")
        firstThreadID = atoi(av[++i]);
      else if (arg == "-ns")
        timeToRun = atof(av[++i]);
      else
        throw std::runtime_error("unknown parameter '"+arg+"'");
    }

    barrier.init(numThreads);
    MyThread **thread = new MyThread *[numThreads];
    for (int i=0;i<numThreads;i++) {
      thread[i] = new MyThread(numThreads);
      thread[i]->start(firstThreadID+i);
    }

    while (1) {
      sleep(1);
      if (done) break;
    }

    for (int i=0;i<numThreads;i++)
      thread[i]->join();
    return 0;
  }

}
<|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 "chrome/common/common_param_traits.h"

#include "chrome/common/chrome_constants.h"
#include "gfx/rect.h"
#include "googleurl/src/gurl.h"
#ifndef EXCLUDE_SKIA_DEPENDENCIES
#include "third_party/skia/include/core/SkBitmap.h"
#endif
#include "webkit/glue/dom_operations.h"

namespace IPC {

#ifndef EXCLUDE_SKIA_DEPENDENCIES

namespace {

struct SkBitmap_Data {
  // The configuration for the bitmap (bits per pixel, etc).
  SkBitmap::Config fConfig;

  // The width of the bitmap in pixels.
  uint32 fWidth;

  // The height of the bitmap in pixels.
  uint32 fHeight;

  void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) {
    fConfig = bitmap.config();
    fWidth = bitmap.width();
    fHeight = bitmap.height();
  }

  // Returns whether |bitmap| successfully initialized.
  bool InitSkBitmapFromData(SkBitmap* bitmap, const char* pixels,
                            size_t total_pixels) const {
    if (total_pixels) {
      bitmap->setConfig(fConfig, fWidth, fHeight, 0);
      if (!bitmap->allocPixels())
        return false;
      if (total_pixels != bitmap->getSize())
        return false;
      memcpy(bitmap->getPixels(), pixels, total_pixels);
    }
    return true;
  }
};

}  // namespace

void ParamTraits<SkBitmap>::Write(Message* m, const SkBitmap& p) {
  size_t fixed_size = sizeof(SkBitmap_Data);
  SkBitmap_Data bmp_data;
  bmp_data.InitSkBitmapDataForTransfer(p);
  m->WriteData(reinterpret_cast<const char*>(&bmp_data),
               static_cast<int>(fixed_size));
  size_t pixel_size = p.getSize();
  SkAutoLockPixels p_lock(p);
  m->WriteData(reinterpret_cast<const char*>(p.getPixels()),
               static_cast<int>(pixel_size));
}

bool ParamTraits<SkBitmap>::Read(const Message* m, void** iter, SkBitmap* r) {
  const char* fixed_data;
  int fixed_data_size = 0;
  if (!m->ReadData(iter, &fixed_data, &fixed_data_size) ||
     (fixed_data_size <= 0)) {
    NOTREACHED();
    return false;
  }
  if (fixed_data_size != sizeof(SkBitmap_Data))
    return false;  // Message is malformed.

  const char* variable_data;
  int variable_data_size = 0;
  if (!m->ReadData(iter, &variable_data, &variable_data_size) ||
     (variable_data_size < 0)) {
    NOTREACHED();
    return false;
  }
  const SkBitmap_Data* bmp_data =
      reinterpret_cast<const SkBitmap_Data*>(fixed_data);
  return bmp_data->InitSkBitmapFromData(r, variable_data, variable_data_size);
}

void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::wstring* l) {
  l->append(StringPrintf(L"<SkBitmap>"));
}

#endif  // EXCLUDE_SKIA_DEPENDENCIES

void ParamTraits<GURL>::Write(Message* m, const GURL& p) {
  m->WriteString(p.possibly_invalid_spec());
  // TODO(brettw) bug 684583: Add encoding for query params.
}

bool ParamTraits<GURL>::Read(const Message* m, void** iter, GURL* p) {
  std::string s;
  if (!m->ReadString(iter, &s) || s.length() > chrome::kMaxURLChars) {
    *p = GURL();
    return false;
  }
  *p = GURL(s);
  return true;
}

void ParamTraits<GURL>::Log(const GURL& p, std::wstring* l) {
  l->append(UTF8ToWide(p.spec()));
}

void ParamTraits<gfx::Point>::Write(Message* m, const gfx::Point& p) {
  m->WriteInt(p.x());
  m->WriteInt(p.y());
}

bool ParamTraits<gfx::Point>::Read(const Message* m, void** iter,
                                   gfx::Point* r) {
  int x, y;
  if (!m->ReadInt(iter, &x) ||
      !m->ReadInt(iter, &y))
    return false;
  r->set_x(x);
  r->set_y(y);
  return true;
}

void ParamTraits<gfx::Point>::Log(const gfx::Point& p, std::wstring* l) {
  l->append(StringPrintf(L"(%d, %d)", p.x(), p.y()));
}

void ParamTraits<gfx::Rect>::Write(Message* m, const gfx::Rect& p) {
  m->WriteInt(p.x());
  m->WriteInt(p.y());
  m->WriteInt(p.width());
  m->WriteInt(p.height());
}

bool ParamTraits<gfx::Rect>::Read(const Message* m, void** iter, gfx::Rect* r) {
  int x, y, w, h;
  if (!m->ReadInt(iter, &x) ||
      !m->ReadInt(iter, &y) ||
      !m->ReadInt(iter, &w) ||
      !m->ReadInt(iter, &h))
    return false;
  r->set_x(x);
  r->set_y(y);
  r->set_width(w);
  r->set_height(h);
  return true;
}

void ParamTraits<gfx::Rect>::Log(const gfx::Rect& p, std::wstring* l) {
  l->append(StringPrintf(L"(%d, %d, %d, %d)", p.x(), p.y(),
                         p.width(), p.height()));
}

void ParamTraits<gfx::Size>::Write(Message* m, const gfx::Size& p) {
  m->WriteInt(p.width());
  m->WriteInt(p.height());
}

bool ParamTraits<gfx::Size>::Read(const Message* m, void** iter, gfx::Size* r) {
  int w, h;
  if (!m->ReadInt(iter, &w) ||
      !m->ReadInt(iter, &h))
    return false;
  r->set_width(w);
  r->set_height(h);
  return true;
}

void ParamTraits<gfx::Size>::Log(const gfx::Size& p, std::wstring* l) {
  l->append(StringPrintf(L"(%d, %d)", p.width(), p.height()));
}

void ParamTraits<ContentSettings>::Write(
    Message* m, const ContentSettings& settings) {
  for (size_t i = 0; i < arraysize(settings.settings); ++i)
    WriteParam(m, settings.settings[i]);
}

bool ParamTraits<ContentSettings>::Read(
    const Message* m, void** iter, ContentSettings* r) {
  for (size_t i = 0; i < arraysize(r->settings); ++i) {
    if (!ReadParam(m, iter, &r->settings[i]))
      return false;
  }
  return true;
}

void ParamTraits<ContentSettings>::Log(
    const ContentSettings& p, std::wstring* l) {
  l->append(StringPrintf(L"<ContentSettings>"));
}

void ParamTraits<webkit_glue::WebApplicationInfo>::Write(
    Message* m, const webkit_glue::WebApplicationInfo& p) {
  WriteParam(m, p.title);
  WriteParam(m, p.description);
  WriteParam(m, p.app_url);
  WriteParam(m, p.icons.size());
  for (size_t i = 0; i < p.icons.size(); ++i) {
    WriteParam(m, p.icons[i].url);
    WriteParam(m, p.icons[i].width);
    WriteParam(m, p.icons[i].height);
  }
}

bool ParamTraits<webkit_glue::WebApplicationInfo>::Read(
    const Message* m, void** iter, webkit_glue::WebApplicationInfo* r) {
  size_t icon_count;
  bool result =
    ReadParam(m, iter, &r->title) &&
    ReadParam(m, iter, &r->description) &&
    ReadParam(m, iter, &r->app_url) &&
    ReadParam(m, iter, &icon_count);
  if (!result)
    return false;
  for (size_t i = 0; i < icon_count; ++i) {
    param_type::IconInfo icon_info;
    result =
        ReadParam(m, iter, &icon_info.url) &&
        ReadParam(m, iter, &icon_info.width) &&
        ReadParam(m, iter, &icon_info.height);
    if (!result)
      return false;
    r->icons.push_back(icon_info);
  }
  return true;
}

void ParamTraits<webkit_glue::WebApplicationInfo>::Log(
    const webkit_glue::WebApplicationInfo& p, std::wstring* l) {
  l->append(L"<WebApplicationInfo>");
}

void ParamTraits<Geoposition::ErrorCode>::Write(
    Message* m, const Geoposition::ErrorCode& p) {
  int error_code = p;
  WriteParam(m, error_code);
}

bool ParamTraits<Geoposition::ErrorCode>::Read(
      const Message* m, void** iter, Geoposition::ErrorCode* p) {
  int error_code_param = 0;
  bool ret = ReadParam(m, iter, &error_code_param);
  *p = static_cast<Geoposition::ErrorCode>(error_code_param);
  return ret;
}

void ParamTraits<Geoposition::ErrorCode>::Log(
    const Geoposition::ErrorCode& p, std::wstring* l) {
  int error_code = p;
  l->append(StringPrintf(L"<Geoposition::ErrorCode>%d", error_code));
}

void ParamTraits<Geoposition>::Write(Message* m, const Geoposition& p) {
  WriteParam(m, p.latitude);
  WriteParam(m, p.longitude);
  WriteParam(m, p.accuracy);
  WriteParam(m, p.altitude);
  WriteParam(m, p.altitude_accuracy);
  WriteParam(m, p.speed);
  WriteParam(m, p.heading);
  WriteParam(m, p.timestamp);
  WriteParam(m, p.error_code);
  WriteParam(m, p.error_message);
}

bool ParamTraits<Geoposition>::Read(
      const Message* m, void** iter, Geoposition* p) {
  bool ret = ReadParam(m, iter, &p->latitude);
  ret = ret && ReadParam(m, iter, &p->longitude);
  ret = ret && ReadParam(m, iter, &p->accuracy);
  ret = ret && ReadParam(m, iter, &p->altitude);
  ret = ret && ReadParam(m, iter, &p->altitude_accuracy);
  ret = ret && ReadParam(m, iter, &p->speed);
  ret = ret && ReadParam(m, iter, &p->heading);
  ret = ret && ReadParam(m, iter, &p->timestamp);
  ret = ret && ReadParam(m, iter, &p->error_code);
  ret = ret && ReadParam(m, iter, &p->error_message);
  return ret;
}

void ParamTraits<Geoposition>::Log(const Geoposition& p, std::wstring* l) {
  l->append(
      StringPrintf(
          L"<Geoposition>"
          L"%.6f %.6f %.6f %.6f "
          L"%.6f %.6f %.6f ",
          p.latitude, p.longitude, p.accuracy, p.altitude,
          p.altitude_accuracy, p.speed, p.heading));
  LogParam(p.timestamp, l);
  l->append(L" ");
  l->append(p.error_message);
  LogParam(p.error_code, l);
}

}  // namespace IPC
<commit_msg>Apply a sanity limit to objects with width & height.<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 "chrome/common/common_param_traits.h"

#include "chrome/common/chrome_constants.h"
#include "gfx/rect.h"
#include "googleurl/src/gurl.h"
#ifndef EXCLUDE_SKIA_DEPENDENCIES
#include "third_party/skia/include/core/SkBitmap.h"
#endif
#include "webkit/glue/dom_operations.h"

namespace IPC {

#ifndef EXCLUDE_SKIA_DEPENDENCIES

namespace {

struct SkBitmap_Data {
  // The configuration for the bitmap (bits per pixel, etc).
  SkBitmap::Config fConfig;

  // The width of the bitmap in pixels.
  uint32 fWidth;

  // The height of the bitmap in pixels.
  uint32 fHeight;

  void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) {
    fConfig = bitmap.config();
    fWidth = bitmap.width();
    fHeight = bitmap.height();
  }

  // Returns whether |bitmap| successfully initialized.
  bool InitSkBitmapFromData(SkBitmap* bitmap, const char* pixels,
                            size_t total_pixels) const {
    if (total_pixels) {
      bitmap->setConfig(fConfig, fWidth, fHeight, 0);
      if (!bitmap->allocPixels())
        return false;
      if (total_pixels != bitmap->getSize())
        return false;
      memcpy(bitmap->getPixels(), pixels, total_pixels);
    }
    return true;
  }
};

}  // namespace

void ParamTraits<SkBitmap>::Write(Message* m, const SkBitmap& p) {
  size_t fixed_size = sizeof(SkBitmap_Data);
  SkBitmap_Data bmp_data;
  bmp_data.InitSkBitmapDataForTransfer(p);
  m->WriteData(reinterpret_cast<const char*>(&bmp_data),
               static_cast<int>(fixed_size));
  size_t pixel_size = p.getSize();
  SkAutoLockPixels p_lock(p);
  m->WriteData(reinterpret_cast<const char*>(p.getPixels()),
               static_cast<int>(pixel_size));
}

bool ParamTraits<SkBitmap>::Read(const Message* m, void** iter, SkBitmap* r) {
  const char* fixed_data;
  int fixed_data_size = 0;
  if (!m->ReadData(iter, &fixed_data, &fixed_data_size) ||
     (fixed_data_size <= 0)) {
    NOTREACHED();
    return false;
  }
  if (fixed_data_size != sizeof(SkBitmap_Data))
    return false;  // Message is malformed.

  const char* variable_data;
  int variable_data_size = 0;
  if (!m->ReadData(iter, &variable_data, &variable_data_size) ||
     (variable_data_size < 0)) {
    NOTREACHED();
    return false;
  }
  const SkBitmap_Data* bmp_data =
      reinterpret_cast<const SkBitmap_Data*>(fixed_data);
  return bmp_data->InitSkBitmapFromData(r, variable_data, variable_data_size);
}

void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::wstring* l) {
  l->append(StringPrintf(L"<SkBitmap>"));
}

#endif  // EXCLUDE_SKIA_DEPENDENCIES

void ParamTraits<GURL>::Write(Message* m, const GURL& p) {
  m->WriteString(p.possibly_invalid_spec());
  // TODO(brettw) bug 684583: Add encoding for query params.
}

bool ParamTraits<GURL>::Read(const Message* m, void** iter, GURL* p) {
  std::string s;
  if (!m->ReadString(iter, &s) || s.length() > chrome::kMaxURLChars) {
    *p = GURL();
    return false;
  }
  *p = GURL(s);
  return true;
}

void ParamTraits<GURL>::Log(const GURL& p, std::wstring* l) {
  l->append(UTF8ToWide(p.spec()));
}

void ParamTraits<gfx::Point>::Write(Message* m, const gfx::Point& p) {
  m->WriteInt(p.x());
  m->WriteInt(p.y());
}

bool ParamTraits<gfx::Point>::Read(const Message* m, void** iter,
                                   gfx::Point* r) {
  int x, y;
  if (!m->ReadInt(iter, &x) ||
      !m->ReadInt(iter, &y))
    return false;
  r->set_x(x);
  r->set_y(y);
  return true;
}

void ParamTraits<gfx::Point>::Log(const gfx::Point& p, std::wstring* l) {
  l->append(StringPrintf(L"(%d, %d)", p.x(), p.y()));
}

void ParamTraits<gfx::Rect>::Write(Message* m, const gfx::Rect& p) {
  m->WriteInt(p.x());
  m->WriteInt(p.y());
  m->WriteInt(p.width());
  m->WriteInt(p.height());
}

bool ParamTraits<gfx::Rect>::Read(const Message* m, void** iter, gfx::Rect* r) {
  int x, y, w, h;
  if (!m->ReadInt(iter, &x) ||
      !m->ReadInt(iter, &y) ||
      !m->ReadInt(iter, &w) ||
      !m->ReadInt(iter, &h))
    return false;
  if (x < 0 || y < 0 || x >= (INT_MAX - w) || y >= (INT_MAX - h) ||
      w < 0 || h < 0 || h >= ((INT_MAX / 16) / (w ? w : 1)))
    return false;
  r->set_x(x);
  r->set_y(y);
  r->set_width(w);
  r->set_height(h);
  return true;
}

void ParamTraits<gfx::Rect>::Log(const gfx::Rect& p, std::wstring* l) {
  l->append(StringPrintf(L"(%d, %d, %d, %d)", p.x(), p.y(),
                         p.width(), p.height()));
}

void ParamTraits<gfx::Size>::Write(Message* m, const gfx::Size& p) {
  m->WriteInt(p.width());
  m->WriteInt(p.height());
}

bool ParamTraits<gfx::Size>::Read(const Message* m, void** iter, gfx::Size* r) {
  int w, h;
  if (!m->ReadInt(iter, &w) ||
      !m->ReadInt(iter, &h))
    return false;
  if (w < 0 || h < 0 || h >= ((INT_MAX / 16) / (w ? w : 1)))
    return false;
  r->set_width(w);
  r->set_height(h);
  return true;
}

void ParamTraits<gfx::Size>::Log(const gfx::Size& p, std::wstring* l) {
  l->append(StringPrintf(L"(%d, %d)", p.width(), p.height()));
}

void ParamTraits<ContentSettings>::Write(
    Message* m, const ContentSettings& settings) {
  for (size_t i = 0; i < arraysize(settings.settings); ++i)
    WriteParam(m, settings.settings[i]);
}

bool ParamTraits<ContentSettings>::Read(
    const Message* m, void** iter, ContentSettings* r) {
  for (size_t i = 0; i < arraysize(r->settings); ++i) {
    if (!ReadParam(m, iter, &r->settings[i]))
      return false;
  }
  return true;
}

void ParamTraits<ContentSettings>::Log(
    const ContentSettings& p, std::wstring* l) {
  l->append(StringPrintf(L"<ContentSettings>"));
}

void ParamTraits<webkit_glue::WebApplicationInfo>::Write(
    Message* m, const webkit_glue::WebApplicationInfo& p) {
  WriteParam(m, p.title);
  WriteParam(m, p.description);
  WriteParam(m, p.app_url);
  WriteParam(m, p.icons.size());
  for (size_t i = 0; i < p.icons.size(); ++i) {
    WriteParam(m, p.icons[i].url);
    WriteParam(m, p.icons[i].width);
    WriteParam(m, p.icons[i].height);
  }
}

bool ParamTraits<webkit_glue::WebApplicationInfo>::Read(
    const Message* m, void** iter, webkit_glue::WebApplicationInfo* r) {
  size_t icon_count;
  bool result =
    ReadParam(m, iter, &r->title) &&
    ReadParam(m, iter, &r->description) &&
    ReadParam(m, iter, &r->app_url) &&
    ReadParam(m, iter, &icon_count);
  if (!result)
    return false;
  for (size_t i = 0; i < icon_count; ++i) {
    param_type::IconInfo icon_info;
    result =
        ReadParam(m, iter, &icon_info.url) &&
        ReadParam(m, iter, &icon_info.width) &&
        ReadParam(m, iter, &icon_info.height);
    if (!result)
      return false;
    r->icons.push_back(icon_info);
  }
  return true;
}

void ParamTraits<webkit_glue::WebApplicationInfo>::Log(
    const webkit_glue::WebApplicationInfo& p, std::wstring* l) {
  l->append(L"<WebApplicationInfo>");
}

void ParamTraits<Geoposition::ErrorCode>::Write(
    Message* m, const Geoposition::ErrorCode& p) {
  int error_code = p;
  WriteParam(m, error_code);
}

bool ParamTraits<Geoposition::ErrorCode>::Read(
      const Message* m, void** iter, Geoposition::ErrorCode* p) {
  int error_code_param = 0;
  bool ret = ReadParam(m, iter, &error_code_param);
  *p = static_cast<Geoposition::ErrorCode>(error_code_param);
  return ret;
}

void ParamTraits<Geoposition::ErrorCode>::Log(
    const Geoposition::ErrorCode& p, std::wstring* l) {
  int error_code = p;
  l->append(StringPrintf(L"<Geoposition::ErrorCode>%d", error_code));
}

void ParamTraits<Geoposition>::Write(Message* m, const Geoposition& p) {
  WriteParam(m, p.latitude);
  WriteParam(m, p.longitude);
  WriteParam(m, p.accuracy);
  WriteParam(m, p.altitude);
  WriteParam(m, p.altitude_accuracy);
  WriteParam(m, p.speed);
  WriteParam(m, p.heading);
  WriteParam(m, p.timestamp);
  WriteParam(m, p.error_code);
  WriteParam(m, p.error_message);
}

bool ParamTraits<Geoposition>::Read(
      const Message* m, void** iter, Geoposition* p) {
  bool ret = ReadParam(m, iter, &p->latitude);
  ret = ret && ReadParam(m, iter, &p->longitude);
  ret = ret && ReadParam(m, iter, &p->accuracy);
  ret = ret && ReadParam(m, iter, &p->altitude);
  ret = ret && ReadParam(m, iter, &p->altitude_accuracy);
  ret = ret && ReadParam(m, iter, &p->speed);
  ret = ret && ReadParam(m, iter, &p->heading);
  ret = ret && ReadParam(m, iter, &p->timestamp);
  ret = ret && ReadParam(m, iter, &p->error_code);
  ret = ret && ReadParam(m, iter, &p->error_message);
  return ret;
}

void ParamTraits<Geoposition>::Log(const Geoposition& p, std::wstring* l) {
  l->append(
      StringPrintf(
          L"<Geoposition>"
          L"%.6f %.6f %.6f %.6f "
          L"%.6f %.6f %.6f ",
          p.latitude, p.longitude, p.accuracy, p.altitude,
          p.altitude_accuracy, p.speed, p.heading));
  LogParam(p.timestamp, l);
  l->append(L" ");
  l->append(p.error_message);
  LogParam(p.error_code, l);
}

}  // namespace IPC
<|endoftext|>


<commit_before>// Copyright (c) 2020 The Orbit 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 "Process.h"

#include <absl/strings/ascii.h>
#include <absl/strings/str_format.h>

#include <algorithm>
#include <cmath>
#include <filesystem>

#include "ElfUtils/ElfFile.h"
#include "OrbitBase/ExecutablePath.h"
#include "OrbitBase/Logging.h"
#include "OrbitBase/ReadFileToString.h"
#include "OrbitBase/Result.h"
#include "ServiceUtils.h"

namespace orbit_service {

void Process::UpdateCpuUsage(utils::Jiffies process_cpu_time, utils::TotalCpuTime total_cpu_time) {
  const auto diff_process_cpu_time =
      static_cast<double>(process_cpu_time.value - previous_process_cpu_time_.value);
  const auto diff_total_cpu_time =
      static_cast<double>(total_cpu_time.jiffies.value - previous_total_cpu_time_.value);

  // When the counters wrap, `cpu_usage` might be smaller than 0.0 or larger than 1.0,
  // depending on the signedness of `Jiffies`. Reference implementations like top and htop usually
  // clamp in this case. So that's what we're also doing here. Since 100% is usually considered
  // the usage of a single logical core, we multiply by the number of cores (cpus) - just like
  // top and htop do as well.
  const auto cpu_usage =
      std::clamp(diff_process_cpu_time / diff_total_cpu_time, 0.0, 1.0) * total_cpu_time.cpus;

  // TODO(hebecker): Rename cpu_usage to cpu_usage_rate and normalize. Being in percent was
  // surprising
  set_cpu_usage(cpu_usage * 100.0);

  previous_process_cpu_time_ = process_cpu_time;
  previous_total_cpu_time_ = total_cpu_time.jiffies;
}

ErrorMessageOr<Process> Process::FromPid(pid_t pid) {
  const auto path = std::filesystem::path{"/proc"} / std::to_string(pid);

  if (!std::filesystem::is_directory(path)) {
    return ErrorMessage{absl::StrFormat("PID %d does not exist", pid)};
  }

  const std::filesystem::path name_file_path = path / "comm";
  auto name_file_result = orbit_base::ReadFileToString(name_file_path);
  if (!name_file_result) {
    return ErrorMessage{absl::StrFormat("Failed to read %s: %s", name_file_path.string(),
                                        name_file_result.error().message())};
  }

  std::string name = std::move(name_file_result.value());
  // Remove new line character.
  absl::StripTrailingAsciiWhitespace(&name);
  if (name.empty()) {
    return ErrorMessage{absl::StrFormat("Could not determine the process name of process %d", pid)};
  }

  Process process{};
  process.set_pid(pid);
  process.set_name(name);

  const auto total_cpu_time = utils::GetCumulativeTotalCpuTime();
  const auto cpu_time = utils::GetCumulativeCpuTimeFromProcess(process.pid());
  if (cpu_time && total_cpu_time) {
    process.UpdateCpuUsage(cpu_time.value(), total_cpu_time.value());
  } else {
    LOG("Could not update the CPU usage of process %d", process.pid());
  }

  // "The command-line arguments appear [...] as a set of strings
  // separated by null bytes ('\0')".
  const std::filesystem::path cmdline_file_path = path / "cmdline";
  auto cmdline_file_result = orbit_base::ReadFileToString(cmdline_file_path);
  if (!cmdline_file_result) {
    return ErrorMessage{absl::StrFormat("Failed to read %s: %s", cmdline_file_path.string(),
                                        cmdline_file_result.error().message())};
  }

  std::string cmdline = std::move(cmdline_file_result.value());
  std::replace(cmdline.begin(), cmdline.end(), '\0', ' ');
  process.set_command_line(cmdline);

  auto file_path_result = orbit_base::GetExecutablePath(pid);
  if (file_path_result) {
    process.set_full_path(std::move(file_path_result.value()));

    const auto& elf_file = orbit_elf_utils::ElfFile::Create(file_path_result.value().string());
    if (elf_file) {
      process.set_is_64_bit(elf_file.value()->Is64Bit());
    } else {
      LOG("Warning: Unable to parse the executable \"%s\" as elf file. (pid: %d)",
          file_path_result.value(), pid);
    }
  }

  return process;
}

}  // namespace orbit_service
<commit_msg>Fix use-after-move for process executable path<commit_after>// Copyright (c) 2020 The Orbit 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 "Process.h"

#include <absl/strings/ascii.h>
#include <absl/strings/str_format.h>

#include <algorithm>
#include <cmath>
#include <filesystem>

#include "ElfUtils/ElfFile.h"
#include "OrbitBase/ExecutablePath.h"
#include "OrbitBase/Logging.h"
#include "OrbitBase/ReadFileToString.h"
#include "OrbitBase/Result.h"
#include "ServiceUtils.h"

namespace orbit_service {

void Process::UpdateCpuUsage(utils::Jiffies process_cpu_time, utils::TotalCpuTime total_cpu_time) {
  const auto diff_process_cpu_time =
      static_cast<double>(process_cpu_time.value - previous_process_cpu_time_.value);
  const auto diff_total_cpu_time =
      static_cast<double>(total_cpu_time.jiffies.value - previous_total_cpu_time_.value);

  // When the counters wrap, `cpu_usage` might be smaller than 0.0 or larger than 1.0,
  // depending on the signedness of `Jiffies`. Reference implementations like top and htop usually
  // clamp in this case. So that's what we're also doing here. Since 100% is usually considered
  // the usage of a single logical core, we multiply by the number of cores (cpus) - just like
  // top and htop do as well.
  const auto cpu_usage =
      std::clamp(diff_process_cpu_time / diff_total_cpu_time, 0.0, 1.0) * total_cpu_time.cpus;

  // TODO(hebecker): Rename cpu_usage to cpu_usage_rate and normalize. Being in percent was
  // surprising
  set_cpu_usage(cpu_usage * 100.0);

  previous_process_cpu_time_ = process_cpu_time;
  previous_total_cpu_time_ = total_cpu_time.jiffies;
}

ErrorMessageOr<Process> Process::FromPid(pid_t pid) {
  const auto path = std::filesystem::path{"/proc"} / std::to_string(pid);

  if (!std::filesystem::is_directory(path)) {
    return ErrorMessage{absl::StrFormat("PID %d does not exist", pid)};
  }

  const std::filesystem::path name_file_path = path / "comm";
  auto name_file_result = orbit_base::ReadFileToString(name_file_path);
  if (!name_file_result) {
    return ErrorMessage{absl::StrFormat("Failed to read %s: %s", name_file_path.string(),
                                        name_file_result.error().message())};
  }

  std::string name = std::move(name_file_result.value());
  // Remove new line character.
  absl::StripTrailingAsciiWhitespace(&name);
  if (name.empty()) {
    return ErrorMessage{absl::StrFormat("Could not determine the process name of process %d", pid)};
  }

  Process process{};
  process.set_pid(pid);
  process.set_name(name);

  const auto total_cpu_time = utils::GetCumulativeTotalCpuTime();
  const auto cpu_time = utils::GetCumulativeCpuTimeFromProcess(process.pid());
  if (cpu_time && total_cpu_time) {
    process.UpdateCpuUsage(cpu_time.value(), total_cpu_time.value());
  } else {
    LOG("Could not update the CPU usage of process %d", process.pid());
  }

  // "The command-line arguments appear [...] as a set of strings
  // separated by null bytes ('\0')".
  const std::filesystem::path cmdline_file_path = path / "cmdline";
  auto cmdline_file_result = orbit_base::ReadFileToString(cmdline_file_path);
  if (!cmdline_file_result) {
    return ErrorMessage{absl::StrFormat("Failed to read %s: %s", cmdline_file_path.string(),
                                        cmdline_file_result.error().message())};
  }

  std::string cmdline = std::move(cmdline_file_result.value());
  std::replace(cmdline.begin(), cmdline.end(), '\0', ' ');
  process.set_command_line(cmdline);

  auto file_path_result = orbit_base::GetExecutablePath(pid);
  if (file_path_result) {
    process.set_full_path(file_path_result.value());

    const auto& elf_file = orbit_elf_utils::ElfFile::Create(file_path_result.value());
    if (elf_file) {
      process.set_is_64_bit(elf_file.value()->Is64Bit());
    } else {
      LOG("Warning: Unable to parse the executable \"%s\" as elf file. (pid: %d)",
          file_path_result.value(), pid);
    }
  }

  return process;
}

}  // namespace orbit_service
<|endoftext|>