<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "itkImageToImageFilter.h"

#include "otbMaximumAutocorrelationFactorImageFilter.h"
#include "otbPCAImageFilter.h"
#include "otbNAPCAImageFilter.h"
#include "otbLocalActivityVectorImageFilter.h"
#include "otbMaximumAutocorrelationFactorImageFilter.h"
#include "otbFastICAImageFilter.h"
#include "otbFastICAInternalOptimizerVectorImageFilter.h"

//#include "otbVirtualDimensionality.h"

#include "otbStreamingMinMaxVectorImageFilter.h"
#include "otbVectorRescaleIntensityImageFilter.h"

namespace otb
{
namespace Wrapper
{

class DimensionalityReduction: public Application
{
public:
  /** Standard class typedefs. */
  typedef DimensionalityReduction Self;
  typedef Application Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  // Dimensionality reduction typedef
  typedef otb::MaximumAutocorrelationFactorImageFilter<FloatVectorImageType, FloatVectorImageType> MAFFilterType;

  typedef itk::ImageToImageFilter<FloatVectorImageType, FloatVectorImageType> DimensionalityReductionFilter;

  // Reduction dimensio filters
  typedef otb::PCAImageFilter<FloatVectorImageType, FloatVectorImageType, otb::Transform::FORWARD> PCAForwardFilterType;
  typedef otb::PCAImageFilter<FloatVectorImageType, FloatVectorImageType, otb::Transform::INVERSE> PCAInverseFilterType;
  //typedef otb::PCAImageFilter< FloatVectorImageType, FloatVectorImageType, otb::Transform::FORWARD >

  typedef otb::LocalActivityVectorImageFilter<FloatVectorImageType, FloatVectorImageType> NoiseFilterType;

  typedef otb::NAPCAImageFilter<FloatVectorImageType, FloatVectorImageType, NoiseFilterType, otb::Transform::FORWARD>
      NAPCAForwardFilterType;
  typedef otb::NAPCAImageFilter<FloatVectorImageType, FloatVectorImageType, NoiseFilterType, otb::Transform::INVERSE>
      NAPCAInverseFilterType;

  typedef otb::MaximumAutocorrelationFactorImageFilter<FloatVectorImageType, FloatVectorImageType> MAFForwardFilterType;

  typedef otb::FastICAImageFilter<FloatVectorImageType, FloatVectorImageType, otb::Transform::FORWARD>
      ICAForwardFilterType;
  typedef otb::FastICAImageFilter<FloatVectorImageType, FloatVectorImageType, otb::Transform::INVERSE>
      ICAInverseFilterType;

  typedef otb::StreamingStatisticsVectorImageFilter<FloatVectorImageType> StreamingStatisticsVectorImageFilterType;

  typedef StreamingStatisticsVectorImageFilterType::MatrixObjectType::ComponentType                 MatrixType;
  //typedef otb::VirtualDimensionality<double> VDFilterType;

  // output rescale
  typedef otb::StreamingMinMaxVectorImageFilter<FloatVectorImageType> MinMaxFilterType;
  typedef otb::VectorRescaleIntensityImageFilter<FloatVectorImageType> RescaleImageFilterType;

  /** Standard macro */
  itkNewMacro(Self)
;

  itkTypeMacro(DimensionalityReduction, otb::Wrapper::Application)
;

private:
  void DoInit()
  {
    SetName("DimensionalityReduction");
    SetDescription("Perform Dimension reduction of the input image.");
    SetDocName("Dimensionality reduction");
    SetDocLongDescription("Performs dimensionality reduction on input image. PCA,NA-PCA,MAF,ICA methods are available. It is also possible to compute the inverse transform to reconstruct the image. It is also possible to optionnaly export the transformation matrix to a text file.");
    SetDocLimitations("This application does not provide the inverse transform and the transformation matrix export for the MAF.");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(
                  "\"Kernel maximum autocorrelation factor and minimum noise fraction transformations,\" IEEE Transactions on Image Processing, vol. 20, no. 3, pp. 612-624, (2011)");

    AddDocTag(Tags::DimensionReduction);
    AddDocTag(Tags::Filter);

    AddParameter(ParameterType_InputImage, "in", "Input Image");
    SetParameterDescription("in", "The input image to apply dimensionality reduction.");
    AddParameter(ParameterType_OutputImage, "out", "Output Image");
    SetParameterDescription("out", "output image. Components are ordered by decreasing eigenvalues.");
    AddParameter(ParameterType_Group, "rescale", "Rescale Output.");

    MandatoryOff("rescale");
    //  AddChoice("rescale.no","No rescale");
    // AddChoice("rescale.minmax","rescale to min max value");

    AddParameter(ParameterType_Float, "rescale.outmin", "Output min value");
    AddParameter(ParameterType_Float, "rescale.outmax", "Output max value");
    SetDefaultParameterFloat("rescale.outmin", 0.0);
    SetParameterDescription("rescale.outmin", "Minimum value of the output image.");
    SetDefaultParameterFloat("rescale.outmax", 255.0);
    SetParameterDescription("rescale.outmax", "Maximum value of the output image.");

    AddParameter(ParameterType_OutputImage, "outinv", " Inverse Output Image");
    SetParameterDescription("outinv", "reconstruct output image.");
    MandatoryOff("outinv");

    AddParameter(ParameterType_Choice, "method", "Algorithm");
    SetParameterDescription("method", "Selection of the reduction dimension method.");

    AddChoice("method.pca", "PCA");
    SetParameterDescription("method.pca", "Principal Component Analysis.");
    AddChoice("method.napca", "NA-PCA");
    SetParameterDescription("method.napca", "Noise Adjusted Principal Component Analysis.");
    AddParameter(ParameterType_Int, "method.napca.radiusx", "Set the x radius of the sliding window.");
    SetMinimumParameterIntValue("method.napca.radiusx", 1);
    SetDefaultParameterInt("method.napca.radiusx", 1);
    AddParameter(ParameterType_Int, "method.napca.radiusy", "Set the y radius of the sliding window.");
    SetMinimumParameterIntValue("method.napca.radiusy", 1);
    SetDefaultParameterInt("method.napca.radiusy", 1);

    AddChoice("method.maf", "MAF");
    SetParameterDescription("method.maf", "Maximum Autocorrelation Factor.");
    AddChoice("method.ica", "ICA");
    SetParameterDescription("method.ica", "Independant Component Analysis.");
    AddParameter(ParameterType_Int, "method.ica.iter", "number of iterations ");
    SetMinimumParameterIntValue("method.ica.iter", 1);
    SetDefaultParameterInt("method.ica.iter", 20);
    MandatoryOff("method.ica.iter");

    AddParameter(ParameterType_Float, "method.ica.mu", "Give the increment weight of W in [0, 1]");
    SetMinimumParameterFloatValue("method.ica.mu", 0.);
    SetMaximumParameterFloatValue("method.ica.mu", 1.);
    SetDefaultParameterFloat("method.ica.mu", 1.);
    MandatoryOff("method.ica.mu");

    //AddChoice("method.vd","virual Dimension");
    //SetParameterDescription("method.vd","Virtual Dimension.");
    //MandatoryOff("method");

    AddParameter(ParameterType_Int, "nbcomp", "Number of Components.");
    SetParameterDescription("nbcomp", "Number of relevant components kept. By default all components are kept.");
    SetDefaultParameterInt("nbcomp", 0);
    MandatoryOff("nbcomp");
    SetMinimumParameterIntValue("nbcomp", 0);

    AddParameter(ParameterType_Empty, "normalize", "Normalize.");
    SetParameterDescription("normalize", "center AND reduce data before Dimensionality reduction.");
    MandatoryOff("normalize");

    AddParameter(ParameterType_OutputFilename, "outmatrix", "Transformation matrix output");
    SetParameterDescription("outmatrix", "Filename to store the transformation matrix (csv format)");
    MandatoryOff("outmatrix");

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "cupriteSubHsi.tif");
    SetDocExampleParameterValue("out", "FilterOutput.tif");
    SetDocExampleParameterValue("method", "pca");
  }

  void DoUpdateParameters()
  {
  }

  void DoExecute()
  {

    // Get Parameters
    int nbComp = GetParameterInt("nbcomp");
    bool normalize = HasValue("normalize");
    bool rescale = IsParameterEnabled("rescale");

    bool invTransform = HasValue("outinv");
    switch (GetParameterInt("method"))
      {
      // PCA Algorithm
      case 0:
        {
        otbAppLogDEBUG( << "PCA Algorithm ");
        PCAForwardFilterType::Pointer filter = PCAForwardFilterType::New();
        m_ForwardFilter = filter;
        PCAInverseFilterType::Pointer invFilter = PCAInverseFilterType::New();
        m_InverseFilter = invFilter;

        filter->SetInput(GetParameterFloatVectorImage("in"));
        filter->SetNumberOfPrincipalComponentsRequired(nbComp);
        filter->SetUseNormalization(normalize);
        m_ForwardFilter->Update();

        if (invTransform)
          {
          invFilter->SetInput(m_ForwardFilter->GetOutput());
          if (normalize)
            {
            otbAppLogINFO( << "Normalization MeanValue :"<<filter->GetMeanValues()<<
                "StdValue :" <<filter->GetStdDevValues() );
            invFilter->SetMeanValues(filter->GetMeanValues());
            invFilter->SetStdDevValues(filter->GetStdDevValues());
            }

          invFilter->SetTransformationMatrix(filter->GetTransformationMatrix());
          m_TransformationMatrix = invFilter->GetTransformationMatrix();
          }

        m_TransformationMatrix = filter->GetTransformationMatrix();

        break;
        }
      case 1:
        {
        otbAppLogDEBUG( << "NA-PCA Algorithm ");

        // NA-PCA

        unsigned int radiusX = static_cast<unsigned int> (GetParameterInt("method.napca.radiusx"));
        unsigned int radiusY = static_cast<unsigned int> (GetParameterInt("method.napca.radiusy"));

        // Noise filtering
        NoiseFilterType::RadiusType radius = { { radiusX, radiusY } };

        NAPCAForwardFilterType::Pointer filter = NAPCAForwardFilterType::New();
        m_ForwardFilter = filter;
        NAPCAInverseFilterType::Pointer invFilter = NAPCAInverseFilterType::New();
        m_InverseFilter = invFilter;

        filter->SetInput(GetParameterFloatVectorImage("in"));
        filter->SetNumberOfPrincipalComponentsRequired(nbComp);
        filter->SetUseNormalization(normalize);
        filter->GetNoiseImageFilter()->SetRadius(radius);
        m_ForwardFilter->Update();
        if (invTransform)
          {
          otbAppLogDEBUG( << "Compute Inverse Transform");
          invFilter->SetInput(m_ForwardFilter->GetOutput());
          invFilter->SetMeanValues(filter->GetMeanValues());
          if (normalize)
            {
            invFilter->SetStdDevValues(filter->GetStdDevValues());
            }

          invFilter->SetTransformationMatrix(filter->GetTransformationMatrix());
          m_TransformationMatrix = invFilter->GetTransformationMatrix();
          }

        m_TransformationMatrix = filter->GetTransformationMatrix();

        break;
        }
      case 2:
        {
        otbAppLogDEBUG( << "MAF Algorithm ");
        MAFForwardFilterType::Pointer filter = MAFForwardFilterType::New();
        m_ForwardFilter = filter;
        filter->SetInput(GetParameterFloatVectorImage("in"));
        m_ForwardFilter->Update();

        otbAppLogINFO( << "V :"<<std::endl<<filter->GetV()<<"Auto-Correlation :"<<std::endl <<filter->GetAutoCorrelation() );

        break;
        }
      case 3:
        {
        otbAppLogDEBUG( << "Fast ICA Algorithm ");

        unsigned int nbIterations = static_cast<unsigned int> (GetParameterInt("method.ica.iter"));
        double mu = static_cast<double> (GetParameterFloat("method.ica.mu"));

        ICAForwardFilterType::Pointer filter = ICAForwardFilterType::New();
        m_ForwardFilter = filter;
        ICAInverseFilterType::Pointer invFilter = ICAInverseFilterType::New();
        m_InverseFilter = invFilter;

        filter->SetInput(GetParameterFloatVectorImage("in"));
        filter->SetNumberOfPrincipalComponentsRequired(nbComp);
        filter->SetNumberOfIterations(nbIterations);
        filter->SetMu(mu);
        m_ForwardFilter->Update();

        if (invTransform)
          {
          otbAppLogDEBUG( << "Compute Inverse Transform");
          invFilter->SetInput(m_ForwardFilter->GetOutput());

          if (normalize)
            {
            invFilter->SetMeanValues(filter->GetMeanValues());
            invFilter->SetStdDevValues(filter->GetStdDevValues());
            }
          invFilter->SetPCATransformationMatrix(filter->GetPCATransformationMatrix());
          invFilter->SetTransformationMatrix(filter->GetTransformationMatrix());
          }

        m_TransformationMatrix = filter->GetTransformationMatrix();

        break;
        }
        /* case 4:
         {
         otbAppLogDEBUG( << "VD Algorithm");

         break;
         }*/

      default:
        {
        otbAppLogFATAL(<<"non defined method "<<GetParameterInt("method")<<std::endl);
        break;

        }
        return;
      }

    if (invTransform)
      {
      if (GetParameterInt("method") == 2) //MAF or VD
        {
        otbAppLogWARNING(<<"This application only provides the forward transform .");
        }
      else SetParameterOutputImage("outinv", m_InverseFilter->GetOutput());
      }

    //Write transformation matrix
    if (this->GetParameterString("outmatrix").size() != 0)
      {
      if (GetParameterInt("method") == 2) //MAF or VD
        {
        otbAppLogWARNING(<<"No transformation matrix available for MAF.");
        }
      else
        {
        //Write transformation matrix
        std::ofstream outFile;
        outFile.open(this->GetParameterString("outmatrix").c_str());
        outFile << std::fixed;
        outFile.precision(10);

        outFile << m_TransformationMatrix;
        outFile.close();
        }
      }

    if (!rescale)
      {
      SetParameterOutputImage("out", m_ForwardFilter->GetOutput());
      }
    else
      {
      otbAppLogDEBUG( << "Rescaling " )
      otbAppLogDEBUG( << "Starting Min/Max computation" )

      m_MinMaxFilter = MinMaxFilterType::New();
      m_MinMaxFilter->SetInput(m_ForwardFilter->GetOutput());
      m_MinMaxFilter->GetStreamer()->SetNumberOfLinesStrippedStreaming(50);

      AddProcess(m_MinMaxFilter->GetStreamer(), "Min/Max computing");
      m_MinMaxFilter->Update();

      otbAppLogDEBUG( << "Min/Max computation done : min=" << m_MinMaxFilter->GetMinimum()
          << " max=" << m_MinMaxFilter->GetMaximum() )

      FloatVectorImageType::PixelType inMin, inMax;

      m_RescaleFilter = RescaleImageFilterType::New();
      m_RescaleFilter->SetInput(m_ForwardFilter->GetOutput());
      m_RescaleFilter->SetInputMinimum(m_MinMaxFilter->GetMinimum());
      m_RescaleFilter->SetInputMaximum(m_MinMaxFilter->GetMaximum());

      FloatVectorImageType::PixelType outMin, outMax;
      outMin.SetSize(m_ForwardFilter->GetOutput()->GetNumberOfComponentsPerPixel());
      outMax.SetSize(m_ForwardFilter->GetOutput()->GetNumberOfComponentsPerPixel());
      outMin.Fill(GetParameterFloat("rescale.outmin"));
      outMax.Fill(GetParameterFloat("rescale.outmax"));

      m_RescaleFilter->SetOutputMinimum(outMin);
      m_RescaleFilter->SetOutputMaximum(outMax);
      m_RescaleFilter->UpdateOutputInformation();

      SetParameterOutputImage("out", m_RescaleFilter->GetOutput());
      }

  }

  MinMaxFilterType::Pointer               m_MinMaxFilter;
  RescaleImageFilterType::Pointer         m_RescaleFilter;
  DimensionalityReductionFilter::Pointer  m_ForwardFilter;
  DimensionalityReductionFilter::Pointer  m_InverseFilter;
  MatrixType                              m_TransformationMatrix;
};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::DimensionalityReduction)
<commit_msg>BUG: disable outinv parameter in case we compute the MAF transformation<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "itkImageToImageFilter.h"

#include "otbMaximumAutocorrelationFactorImageFilter.h"
#include "otbPCAImageFilter.h"
#include "otbNAPCAImageFilter.h"
#include "otbLocalActivityVectorImageFilter.h"
#include "otbMaximumAutocorrelationFactorImageFilter.h"
#include "otbFastICAImageFilter.h"
#include "otbFastICAInternalOptimizerVectorImageFilter.h"

//#include "otbVirtualDimensionality.h"

#include "otbStreamingMinMaxVectorImageFilter.h"
#include "otbVectorRescaleIntensityImageFilter.h"

namespace otb
{
namespace Wrapper
{

class DimensionalityReduction: public Application
{
public:
  /** Standard class typedefs. */
  typedef DimensionalityReduction Self;
  typedef Application Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  // Dimensionality reduction typedef
  typedef otb::MaximumAutocorrelationFactorImageFilter<FloatVectorImageType, FloatVectorImageType> MAFFilterType;

  typedef itk::ImageToImageFilter<FloatVectorImageType, FloatVectorImageType> DimensionalityReductionFilter;

  // Reduction dimensio filters
  typedef otb::PCAImageFilter<FloatVectorImageType, FloatVectorImageType, otb::Transform::FORWARD> PCAForwardFilterType;
  typedef otb::PCAImageFilter<FloatVectorImageType, FloatVectorImageType, otb::Transform::INVERSE> PCAInverseFilterType;
  //typedef otb::PCAImageFilter< FloatVectorImageType, FloatVectorImageType, otb::Transform::FORWARD >

  typedef otb::LocalActivityVectorImageFilter<FloatVectorImageType, FloatVectorImageType> NoiseFilterType;

  typedef otb::NAPCAImageFilter<FloatVectorImageType, FloatVectorImageType, NoiseFilterType, otb::Transform::FORWARD>
      NAPCAForwardFilterType;
  typedef otb::NAPCAImageFilter<FloatVectorImageType, FloatVectorImageType, NoiseFilterType, otb::Transform::INVERSE>
      NAPCAInverseFilterType;

  typedef otb::MaximumAutocorrelationFactorImageFilter<FloatVectorImageType, FloatVectorImageType> MAFForwardFilterType;

  typedef otb::FastICAImageFilter<FloatVectorImageType, FloatVectorImageType, otb::Transform::FORWARD>
      ICAForwardFilterType;
  typedef otb::FastICAImageFilter<FloatVectorImageType, FloatVectorImageType, otb::Transform::INVERSE>
      ICAInverseFilterType;

  typedef otb::StreamingStatisticsVectorImageFilter<FloatVectorImageType> StreamingStatisticsVectorImageFilterType;

  typedef StreamingStatisticsVectorImageFilterType::MatrixObjectType::ComponentType                 MatrixType;
  //typedef otb::VirtualDimensionality<double> VDFilterType;

  // output rescale
  typedef otb::StreamingMinMaxVectorImageFilter<FloatVectorImageType> MinMaxFilterType;
  typedef otb::VectorRescaleIntensityImageFilter<FloatVectorImageType> RescaleImageFilterType;

  /** Standard macro */
  itkNewMacro(Self)
;

  itkTypeMacro(DimensionalityReduction, otb::Wrapper::Application)
;

private:
  void DoInit()
  {
    SetName("DimensionalityReduction");
    SetDescription("Perform Dimension reduction of the input image.");
    SetDocName("Dimensionality reduction");
    SetDocLongDescription("Performs dimensionality reduction on input image. PCA,NA-PCA,MAF,ICA methods are available. It is also possible to compute the inverse transform to reconstruct the image. It is also possible to optionnaly export the transformation matrix to a text file.");
    SetDocLimitations("This application does not provide the inverse transform and the transformation matrix export for the MAF.");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(
                  "\"Kernel maximum autocorrelation factor and minimum noise fraction transformations,\" IEEE Transactions on Image Processing, vol. 20, no. 3, pp. 612-624, (2011)");

    AddDocTag(Tags::DimensionReduction);
    AddDocTag(Tags::Filter);

    AddParameter(ParameterType_InputImage, "in", "Input Image");
    SetParameterDescription("in", "The input image to apply dimensionality reduction.");
    AddParameter(ParameterType_OutputImage, "out", "Output Image");
    SetParameterDescription("out", "output image. Components are ordered by decreasing eigenvalues.");
    AddParameter(ParameterType_Group, "rescale", "Rescale Output.");

    MandatoryOff("rescale");
    //  AddChoice("rescale.no","No rescale");
    // AddChoice("rescale.minmax","rescale to min max value");

    AddParameter(ParameterType_Float, "rescale.outmin", "Output min value");
    AddParameter(ParameterType_Float, "rescale.outmax", "Output max value");
    SetDefaultParameterFloat("rescale.outmin", 0.0);
    SetParameterDescription("rescale.outmin", "Minimum value of the output image.");
    SetDefaultParameterFloat("rescale.outmax", 255.0);
    SetParameterDescription("rescale.outmax", "Maximum value of the output image.");

    AddParameter(ParameterType_OutputImage, "outinv", " Inverse Output Image");
    SetParameterDescription("outinv", "reconstruct output image.");
    MandatoryOff("outinv");

    AddParameter(ParameterType_Choice, "method", "Algorithm");
    SetParameterDescription("method", "Selection of the reduction dimension method.");

    AddChoice("method.pca", "PCA");
    SetParameterDescription("method.pca", "Principal Component Analysis.");
    AddChoice("method.napca", "NA-PCA");
    SetParameterDescription("method.napca", "Noise Adjusted Principal Component Analysis.");
    AddParameter(ParameterType_Int, "method.napca.radiusx", "Set the x radius of the sliding window.");
    SetMinimumParameterIntValue("method.napca.radiusx", 1);
    SetDefaultParameterInt("method.napca.radiusx", 1);
    AddParameter(ParameterType_Int, "method.napca.radiusy", "Set the y radius of the sliding window.");
    SetMinimumParameterIntValue("method.napca.radiusy", 1);
    SetDefaultParameterInt("method.napca.radiusy", 1);

    AddChoice("method.maf", "MAF");
    SetParameterDescription("method.maf", "Maximum Autocorrelation Factor.");
    AddChoice("method.ica", "ICA");
    SetParameterDescription("method.ica", "Independant Component Analysis.");
    AddParameter(ParameterType_Int, "method.ica.iter", "number of iterations ");
    SetMinimumParameterIntValue("method.ica.iter", 1);
    SetDefaultParameterInt("method.ica.iter", 20);
    MandatoryOff("method.ica.iter");

    AddParameter(ParameterType_Float, "method.ica.mu", "Give the increment weight of W in [0, 1]");
    SetMinimumParameterFloatValue("method.ica.mu", 0.);
    SetMaximumParameterFloatValue("method.ica.mu", 1.);
    SetDefaultParameterFloat("method.ica.mu", 1.);
    MandatoryOff("method.ica.mu");

    //AddChoice("method.vd","virual Dimension");
    //SetParameterDescription("method.vd","Virtual Dimension.");
    //MandatoryOff("method");

    AddParameter(ParameterType_Int, "nbcomp", "Number of Components.");
    SetParameterDescription("nbcomp", "Number of relevant components kept. By default all components are kept.");
    SetDefaultParameterInt("nbcomp", 0);
    MandatoryOff("nbcomp");
    SetMinimumParameterIntValue("nbcomp", 0);

    AddParameter(ParameterType_Empty, "normalize", "Normalize.");
    SetParameterDescription("normalize", "center AND reduce data before Dimensionality reduction.");
    MandatoryOff("normalize");

    AddParameter(ParameterType_OutputFilename, "outmatrix", "Transformation matrix output");
    SetParameterDescription("outmatrix", "Filename to store the transformation matrix (csv format)");
    MandatoryOff("outmatrix");

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "cupriteSubHsi.tif");
    SetDocExampleParameterValue("out", "FilterOutput.tif");
    SetDocExampleParameterValue("method", "pca");
  }

  void DoUpdateParameters()
  {
  }

  void DoExecute()
  {

    // Get Parameters
    int nbComp = GetParameterInt("nbcomp");
    bool normalize = HasValue("normalize");
    bool rescale = IsParameterEnabled("rescale");

    bool invTransform = HasValue("outinv");
    switch (GetParameterInt("method"))
      {
      // PCA Algorithm
      case 0:
        {
        otbAppLogDEBUG( << "PCA Algorithm ");
        PCAForwardFilterType::Pointer filter = PCAForwardFilterType::New();
        m_ForwardFilter = filter;
        PCAInverseFilterType::Pointer invFilter = PCAInverseFilterType::New();
        m_InverseFilter = invFilter;

        filter->SetInput(GetParameterFloatVectorImage("in"));
        filter->SetNumberOfPrincipalComponentsRequired(nbComp);
        filter->SetUseNormalization(normalize);
        m_ForwardFilter->Update();

        if (invTransform)
          {
          invFilter->SetInput(m_ForwardFilter->GetOutput());
          if (normalize)
            {
            otbAppLogINFO( << "Normalization MeanValue :"<<filter->GetMeanValues()<<
                "StdValue :" <<filter->GetStdDevValues() );
            invFilter->SetMeanValues(filter->GetMeanValues());
            invFilter->SetStdDevValues(filter->GetStdDevValues());
            }

          invFilter->SetTransformationMatrix(filter->GetTransformationMatrix());
          m_TransformationMatrix = invFilter->GetTransformationMatrix();
          }

        m_TransformationMatrix = filter->GetTransformationMatrix();

        break;
        }
      case 1:
        {
        otbAppLogDEBUG( << "NA-PCA Algorithm ");

        // NA-PCA

        unsigned int radiusX = static_cast<unsigned int> (GetParameterInt("method.napca.radiusx"));
        unsigned int radiusY = static_cast<unsigned int> (GetParameterInt("method.napca.radiusy"));

        // Noise filtering
        NoiseFilterType::RadiusType radius = { { radiusX, radiusY } };

        NAPCAForwardFilterType::Pointer filter = NAPCAForwardFilterType::New();
        m_ForwardFilter = filter;
        NAPCAInverseFilterType::Pointer invFilter = NAPCAInverseFilterType::New();
        m_InverseFilter = invFilter;

        filter->SetInput(GetParameterFloatVectorImage("in"));
        filter->SetNumberOfPrincipalComponentsRequired(nbComp);
        filter->SetUseNormalization(normalize);
        filter->GetNoiseImageFilter()->SetRadius(radius);
        m_ForwardFilter->Update();
        if (invTransform)
          {
          otbAppLogDEBUG( << "Compute Inverse Transform");
          invFilter->SetInput(m_ForwardFilter->GetOutput());
          invFilter->SetMeanValues(filter->GetMeanValues());
          if (normalize)
            {
            invFilter->SetStdDevValues(filter->GetStdDevValues());
            }

          invFilter->SetTransformationMatrix(filter->GetTransformationMatrix());
          m_TransformationMatrix = invFilter->GetTransformationMatrix();
          }

        m_TransformationMatrix = filter->GetTransformationMatrix();

        break;
        }
      case 2:
        {
        otbAppLogDEBUG( << "MAF Algorithm ");
        MAFForwardFilterType::Pointer filter = MAFForwardFilterType::New();
        m_ForwardFilter = filter;
        filter->SetInput(GetParameterFloatVectorImage("in"));
        m_ForwardFilter->Update();

        otbAppLogINFO( << "V :"<<std::endl<<filter->GetV()<<"Auto-Correlation :"<<std::endl <<filter->GetAutoCorrelation() );

        break;
        }
      case 3:
        {
        otbAppLogDEBUG( << "Fast ICA Algorithm ");

        unsigned int nbIterations = static_cast<unsigned int> (GetParameterInt("method.ica.iter"));
        double mu = static_cast<double> (GetParameterFloat("method.ica.mu"));

        ICAForwardFilterType::Pointer filter = ICAForwardFilterType::New();
        m_ForwardFilter = filter;
        ICAInverseFilterType::Pointer invFilter = ICAInverseFilterType::New();
        m_InverseFilter = invFilter;

        filter->SetInput(GetParameterFloatVectorImage("in"));
        filter->SetNumberOfPrincipalComponentsRequired(nbComp);
        filter->SetNumberOfIterations(nbIterations);
        filter->SetMu(mu);
        m_ForwardFilter->Update();

        if (invTransform)
          {
          otbAppLogDEBUG( << "Compute Inverse Transform");
          invFilter->SetInput(m_ForwardFilter->GetOutput());

          if (normalize)
            {
            invFilter->SetMeanValues(filter->GetMeanValues());
            invFilter->SetStdDevValues(filter->GetStdDevValues());
            }
          invFilter->SetPCATransformationMatrix(filter->GetPCATransformationMatrix());
          invFilter->SetTransformationMatrix(filter->GetTransformationMatrix());
          }

        m_TransformationMatrix = filter->GetTransformationMatrix();

        break;
        }
        /* case 4:
         {
         otbAppLogDEBUG( << "VD Algorithm");

         break;
         }*/

      default:
        {
        otbAppLogFATAL(<<"non defined method "<<GetParameterInt("method")<<std::endl);
        break;

        }
        return;
      }

    if (invTransform)
      {
      if (GetParameterInt("method") == 2) //MAF or VD
        {
        this->DisableParameter("outinv");
        otbAppLogWARNING(<<"This application only provides the forward transform for the MAF method.");
        }
      else SetParameterOutputImage("outinv", m_InverseFilter->GetOutput());
      }

    //Write transformation matrix
    if (this->GetParameterString("outmatrix").size() != 0)
      {
      if (GetParameterInt("method") == 2) //MAF or VD
        {
        otbAppLogWARNING(<<"No transformation matrix available for MAF.");
        }
      else
        {
        //Write transformation matrix
        std::ofstream outFile;
        outFile.open(this->GetParameterString("outmatrix").c_str());
        outFile << std::fixed;
        outFile.precision(10);

        outFile << m_TransformationMatrix;
        outFile.close();
        }
      }

    if (!rescale)
      {
      SetParameterOutputImage("out", m_ForwardFilter->GetOutput());
      }
    else
      {
      otbAppLogDEBUG( << "Rescaling " )
      otbAppLogDEBUG( << "Starting Min/Max computation" )

      m_MinMaxFilter = MinMaxFilterType::New();
      m_MinMaxFilter->SetInput(m_ForwardFilter->GetOutput());
      m_MinMaxFilter->GetStreamer()->SetNumberOfLinesStrippedStreaming(50);

      AddProcess(m_MinMaxFilter->GetStreamer(), "Min/Max computing");
      m_MinMaxFilter->Update();

      otbAppLogDEBUG( << "Min/Max computation done : min=" << m_MinMaxFilter->GetMinimum()
          << " max=" << m_MinMaxFilter->GetMaximum() )

      FloatVectorImageType::PixelType inMin, inMax;

      m_RescaleFilter = RescaleImageFilterType::New();
      m_RescaleFilter->SetInput(m_ForwardFilter->GetOutput());
      m_RescaleFilter->SetInputMinimum(m_MinMaxFilter->GetMinimum());
      m_RescaleFilter->SetInputMaximum(m_MinMaxFilter->GetMaximum());

      FloatVectorImageType::PixelType outMin, outMax;
      outMin.SetSize(m_ForwardFilter->GetOutput()->GetNumberOfComponentsPerPixel());
      outMax.SetSize(m_ForwardFilter->GetOutput()->GetNumberOfComponentsPerPixel());
      outMin.Fill(GetParameterFloat("rescale.outmin"));
      outMax.Fill(GetParameterFloat("rescale.outmax"));

      m_RescaleFilter->SetOutputMinimum(outMin);
      m_RescaleFilter->SetOutputMaximum(outMax);
      m_RescaleFilter->UpdateOutputInformation();

      SetParameterOutputImage("out", m_RescaleFilter->GetOutput());
      }

  }

  MinMaxFilterType::Pointer               m_MinMaxFilter;
  RescaleImageFilterType::Pointer         m_RescaleFilter;
  DimensionalityReductionFilter::Pointer  m_ForwardFilter;
  DimensionalityReductionFilter::Pointer  m_InverseFilter;
  MatrixType                              m_TransformationMatrix;
};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::DimensionalityReduction)
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: i18nhelp.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2003-12-01 13:05:40 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <i18nhelp.hxx>

/*
#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#endif

#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
*/

// #include <cppuhelper/servicefactory.hxx>

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

#ifndef _COM_SUN_STAR_I18N_TRANSLITERATIONMODULES_HPP_
#include <com/sun/star/i18n/TransliterationModules.hpp>
#endif

#ifndef _UNOTOOLS_LOCALEDATAWRAPPER_HXX
#include <unotools/localedatawrapper.hxx>
#endif

#ifndef _UNOTOOLS_TRANSLITERATIONWRAPPER_HXX
#include <unotools/transliterationwrapper.hxx>
#endif

#ifndef _ISOLANG_HXX
#include <tools/isolang.hxx>
#endif

using namespace ::com::sun::star;

vcl::I18nHelper::I18nHelper(  ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxMSF, const ::com::sun::star::lang::Locale& rLocale )
{
    mxMSF = rxMSF;
    maLocale = rLocale;
    mpLocaleDataWrapper = NULL;
    mpTransliterationWrapper= NULL;
    mbTransliterateIgnoreCase = sal_False;
}

vcl::I18nHelper::~I18nHelper()
{
    ImplDestroyWrappers();
}

void vcl::I18nHelper::ImplDestroyWrappers()
{
    delete mpLocaleDataWrapper;
    mpLocaleDataWrapper = NULL;

    delete mpTransliterationWrapper;
    mpTransliterationWrapper= NULL;
}

utl::TransliterationWrapper& vcl::I18nHelper::ImplGetTransliterationWrapper() const
{
    if ( !mpTransliterationWrapper )
    {
        sal_Int32 nModules = i18n::TransliterationModules_IGNORE_WIDTH;
        if ( mbTransliterateIgnoreCase )
            nModules |= i18n::TransliterationModules_IGNORE_CASE;

        ((vcl::I18nHelper*)this)->mpTransliterationWrapper = new utl::TransliterationWrapper( mxMSF, (i18n::TransliterationModules)nModules );
        ((vcl::I18nHelper*)this)->mpTransliterationWrapper->loadModuleIfNeeded( ConvertIsoNamesToLanguage( maLocale.Language, maLocale.Country ) );
    }
    return *mpTransliterationWrapper;
}

LocaleDataWrapper& vcl::I18nHelper::ImplGetLocaleDataWrapper() const
{
    if ( !mpLocaleDataWrapper )
    {
        ((vcl::I18nHelper*)this)->mpLocaleDataWrapper = new LocaleDataWrapper( mxMSF, maLocale );
    }
    return *mpLocaleDataWrapper;
}

const ::com::sun::star::lang::Locale& vcl::I18nHelper::getLocale() const
{
    return maLocale;
}

sal_Int32 vcl::I18nHelper::CompareString( const String& rStr1, const String& rStr2 ) const
{
    ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );

    if ( mbTransliterateIgnoreCase )
    {
        // Change mbTransliterateIgnoreCase and destroy the warpper, next call to
        // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
        ((vcl::I18nHelper*)this)->mbTransliterateIgnoreCase = FALSE;
        delete ((vcl::I18nHelper*)this)->mpTransliterationWrapper;
        ((vcl::I18nHelper*)this)->mpTransliterationWrapper = NULL;
    }

    return ImplGetTransliterationWrapper().compareString( rStr1, rStr2 );
}

sal_Bool vcl::I18nHelper::MatchString( const String& rStr1, const String& rStr2 ) const
{
    ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );

    if ( !mbTransliterateIgnoreCase )
    {
        // Change mbTransliterateIgnoreCase and destroy the warpper, next call to
        // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
        ((vcl::I18nHelper*)this)->mbTransliterateIgnoreCase = TRUE;
        delete ((vcl::I18nHelper*)this)->mpTransliterationWrapper;
        ((vcl::I18nHelper*)this)->mpTransliterationWrapper = NULL;
    }

    return ImplGetTransliterationWrapper().isMatch( rStr1, rStr2 );
}

sal_Bool vcl::I18nHelper::MatchMnemonic( const String& rString, sal_Unicode cMnemonicChar ) const
{
    ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );

    BOOL bEqual = FALSE;
    USHORT n = rString.Search( '~' );
    if ( n != STRING_NOTFOUND )
    {
        String aMatchStr( rString, n+1, STRING_LEN );   // not only one char, because of transliteration...
        bEqual = MatchString( cMnemonicChar, aMatchStr );
    }
    return bEqual;
}

String vcl::I18nHelper::GetDate( const Date& rDate ) const
{
    ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );

    return ImplGetLocaleDataWrapper().getDate( rDate );
}

String vcl::I18nHelper::GetNum( long nNumber, USHORT nDecimals, BOOL bUseThousandSep, BOOL bTrailingZeros ) const
{
    return ImplGetLocaleDataWrapper().getNum( nNumber, nDecimals, bUseThousandSep, bTrailingZeros );
}
<commit_msg>INTEGRATION: CWS ooo19126 (1.4.556); FILE MERGED 2005/09/05 14:44:36 rt 1.4.556.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: i18nhelp.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 11:40:26 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <i18nhelp.hxx>

/*
#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#endif

#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
*/

// #include <cppuhelper/servicefactory.hxx>

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

#ifndef _COM_SUN_STAR_I18N_TRANSLITERATIONMODULES_HPP_
#include <com/sun/star/i18n/TransliterationModules.hpp>
#endif

#ifndef _UNOTOOLS_LOCALEDATAWRAPPER_HXX
#include <unotools/localedatawrapper.hxx>
#endif

#ifndef _UNOTOOLS_TRANSLITERATIONWRAPPER_HXX
#include <unotools/transliterationwrapper.hxx>
#endif

#ifndef _ISOLANG_HXX
#include <tools/isolang.hxx>
#endif

using namespace ::com::sun::star;

vcl::I18nHelper::I18nHelper(  ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxMSF, const ::com::sun::star::lang::Locale& rLocale )
{
    mxMSF = rxMSF;
    maLocale = rLocale;
    mpLocaleDataWrapper = NULL;
    mpTransliterationWrapper= NULL;
    mbTransliterateIgnoreCase = sal_False;
}

vcl::I18nHelper::~I18nHelper()
{
    ImplDestroyWrappers();
}

void vcl::I18nHelper::ImplDestroyWrappers()
{
    delete mpLocaleDataWrapper;
    mpLocaleDataWrapper = NULL;

    delete mpTransliterationWrapper;
    mpTransliterationWrapper= NULL;
}

utl::TransliterationWrapper& vcl::I18nHelper::ImplGetTransliterationWrapper() const
{
    if ( !mpTransliterationWrapper )
    {
        sal_Int32 nModules = i18n::TransliterationModules_IGNORE_WIDTH;
        if ( mbTransliterateIgnoreCase )
            nModules |= i18n::TransliterationModules_IGNORE_CASE;

        ((vcl::I18nHelper*)this)->mpTransliterationWrapper = new utl::TransliterationWrapper( mxMSF, (i18n::TransliterationModules)nModules );
        ((vcl::I18nHelper*)this)->mpTransliterationWrapper->loadModuleIfNeeded( ConvertIsoNamesToLanguage( maLocale.Language, maLocale.Country ) );
    }
    return *mpTransliterationWrapper;
}

LocaleDataWrapper& vcl::I18nHelper::ImplGetLocaleDataWrapper() const
{
    if ( !mpLocaleDataWrapper )
    {
        ((vcl::I18nHelper*)this)->mpLocaleDataWrapper = new LocaleDataWrapper( mxMSF, maLocale );
    }
    return *mpLocaleDataWrapper;
}

const ::com::sun::star::lang::Locale& vcl::I18nHelper::getLocale() const
{
    return maLocale;
}

sal_Int32 vcl::I18nHelper::CompareString( const String& rStr1, const String& rStr2 ) const
{
    ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );

    if ( mbTransliterateIgnoreCase )
    {
        // Change mbTransliterateIgnoreCase and destroy the warpper, next call to
        // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
        ((vcl::I18nHelper*)this)->mbTransliterateIgnoreCase = FALSE;
        delete ((vcl::I18nHelper*)this)->mpTransliterationWrapper;
        ((vcl::I18nHelper*)this)->mpTransliterationWrapper = NULL;
    }

    return ImplGetTransliterationWrapper().compareString( rStr1, rStr2 );
}

sal_Bool vcl::I18nHelper::MatchString( const String& rStr1, const String& rStr2 ) const
{
    ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );

    if ( !mbTransliterateIgnoreCase )
    {
        // Change mbTransliterateIgnoreCase and destroy the warpper, next call to
        // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
        ((vcl::I18nHelper*)this)->mbTransliterateIgnoreCase = TRUE;
        delete ((vcl::I18nHelper*)this)->mpTransliterationWrapper;
        ((vcl::I18nHelper*)this)->mpTransliterationWrapper = NULL;
    }

    return ImplGetTransliterationWrapper().isMatch( rStr1, rStr2 );
}

sal_Bool vcl::I18nHelper::MatchMnemonic( const String& rString, sal_Unicode cMnemonicChar ) const
{
    ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );

    BOOL bEqual = FALSE;
    USHORT n = rString.Search( '~' );
    if ( n != STRING_NOTFOUND )
    {
        String aMatchStr( rString, n+1, STRING_LEN );   // not only one char, because of transliteration...
        bEqual = MatchString( cMnemonicChar, aMatchStr );
    }
    return bEqual;
}

String vcl::I18nHelper::GetDate( const Date& rDate ) const
{
    ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );

    return ImplGetLocaleDataWrapper().getDate( rDate );
}

String vcl::I18nHelper::GetNum( long nNumber, USHORT nDecimals, BOOL bUseThousandSep, BOOL bTrailingZeros ) const
{
    return ImplGetLocaleDataWrapper().getNum( nNumber, nDecimals, bUseThousandSep, bTrailingZeros );
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: svpbmp.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2007-11-01 14:48:17 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "svpbmp.hxx"

#include <basegfx/vector/b2ivector.hxx>
#include <basegfx/range/b2irange.hxx>
#include <basebmp/scanlineformats.hxx>
#include <basebmp/color.hxx>

#include <vcl/salbtype.hxx>
#include <vcl/bitmap.hxx>

using namespace basebmp;
using namespace basegfx;

SvpSalBitmap::~SvpSalBitmap()
{
}

bool SvpSalBitmap::Create( const Size& rSize,
                           USHORT nBitCount,
                           const BitmapPalette& rPalette )
{
    sal_uInt32 nFormat = SVP_DEFAULT_BITMAP_FORMAT;
    switch( nBitCount )
    {
        case 1: nFormat = Format::ONE_BIT_MSB_PAL; break;
        case 4: nFormat = Format::FOUR_BIT_MSB_PAL; break;
        case 8: nFormat = Format::EIGHT_BIT_PAL; break;
#ifdef OSL_BIGENDIAN
        case 16: nFormat = Format::SIXTEEN_BIT_MSB_TC_MASK; break;
#else
        case 16: nFormat = Format::SIXTEEN_BIT_LSB_TC_MASK; break;
#endif
        case 24: nFormat = Format::TWENTYFOUR_BIT_TC_MASK; break;
        case 32: nFormat = Format::THIRTYTWO_BIT_TC_MASK; break;
    }
    B2IVector aSize( rSize.Width(), rSize.Height() );
    if( aSize.getX() == 0 )
        aSize.setX( 1 );
    if( aSize.getY() == 0 )
        aSize.setY( 1 );
    if( nBitCount > 8 )
        m_aBitmap = createBitmapDevice( aSize, false, nFormat );
    else
    {
        // prepare palette
        unsigned int nEntries = 1U << nBitCount;
        std::vector<basebmp::Color>* pPalette =
            new std::vector<basebmp::Color>( nEntries, basebmp::Color(COL_WHITE) );
        unsigned int nColors = rPalette.GetEntryCount();
        for( unsigned int i = 0; i < nColors; i++ )
        {
            const BitmapColor& rCol = rPalette[i];
            (*pPalette)[i] = basebmp::Color( rCol.GetRed(), rCol.GetGreen(), rCol.GetBlue() );
        }
        m_aBitmap = createBitmapDevice( aSize, false, nFormat,
                                        basebmp::RawMemorySharedArray(),
                                        basebmp::PaletteMemorySharedVector( pPalette )
                                        );
    }
    return true;
}

bool SvpSalBitmap::Create( const SalBitmap& rSalBmp )
{
    const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBmp);
    const BitmapDeviceSharedPtr& rSrcBmp = rSrc.getBitmap();
    if( rSrcBmp.get() )
    {
        B2IVector aSize = rSrcBmp->getSize();
        m_aBitmap = cloneBitmapDevice( aSize, rSrcBmp );
        B2IRange aRect( 0, 0, aSize.getX(), aSize.getY() );
        m_aBitmap->drawBitmap( rSrcBmp, aRect, aRect, DrawMode_PAINT );
    }
    else
        m_aBitmap.reset();

    return true;
}

bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
                           SalGraphics* /*pGraphics*/ )
{
    return false;
}

bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
                           USHORT /*nNewBitCount*/ )
{
    return false;
}

void SvpSalBitmap::Destroy()
{
    m_aBitmap.reset();
}

Size SvpSalBitmap::GetSize() const
{
    Size aSize;
    if( m_aBitmap.get() )
    {
        B2IVector aVec( m_aBitmap->getSize() );
        aSize = Size( aVec.getX(), aVec.getY() );
    }

    return aSize;
}

USHORT SvpSalBitmap::GetBitCount() const
{
    USHORT nDepth = 0;
    if( m_aBitmap.get() )
        nDepth = getBitCountFromScanlineFormat( m_aBitmap->getScanlineFormat() );
    return nDepth;
}

BitmapBuffer* SvpSalBitmap::AcquireBuffer( bool )
{
    BitmapBuffer* pBuf = NULL;
    if( m_aBitmap.get() )
    {
        pBuf = new BitmapBuffer();
        USHORT nBitCount = 1;
        switch( m_aBitmap->getScanlineFormat() )
        {
            case Format::ONE_BIT_MSB_GREY:
            case Format::ONE_BIT_MSB_PAL:
                nBitCount = 1;
                pBuf->mnFormat = BMP_FORMAT_1BIT_MSB_PAL;
                break;
            case Format::ONE_BIT_LSB_GREY:
            case Format::ONE_BIT_LSB_PAL:
                nBitCount = 1;
                pBuf->mnFormat = BMP_FORMAT_1BIT_LSB_PAL;
                break;
            case Format::FOUR_BIT_MSB_GREY:
            case Format::FOUR_BIT_MSB_PAL:
                nBitCount = 4;
                pBuf->mnFormat = BMP_FORMAT_4BIT_MSN_PAL;
                break;
            case Format::FOUR_BIT_LSB_GREY:
            case Format::FOUR_BIT_LSB_PAL:
                nBitCount = 4;
                pBuf->mnFormat = BMP_FORMAT_4BIT_LSN_PAL;
                break;
            case Format::EIGHT_BIT_PAL:
                nBitCount = 8;
                pBuf->mnFormat = BMP_FORMAT_8BIT_PAL;
                break;
            case Format::EIGHT_BIT_GREY:
                nBitCount = 8;
                pBuf->mnFormat = BMP_FORMAT_8BIT_PAL;
                break;
            case Format::SIXTEEN_BIT_LSB_TC_MASK:
                nBitCount = 16;
                pBuf->mnFormat = BMP_FORMAT_16BIT_TC_LSB_MASK;
                pBuf->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f );
                break;
            case Format::SIXTEEN_BIT_MSB_TC_MASK:
                nBitCount = 16;
                pBuf->mnFormat = BMP_FORMAT_16BIT_TC_MSB_MASK;
                pBuf->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f );
                break;
            case Format::TWENTYFOUR_BIT_TC_MASK:
                nBitCount = 24;
                pBuf->mnFormat = BMP_FORMAT_24BIT_TC_BGR;
                break;
            case Format::THIRTYTWO_BIT_TC_MASK:
                nBitCount = 32;
                pBuf->mnFormat = BMP_FORMAT_32BIT_TC_MASK;
#ifdef OSL_BIGENDIAN
                pBuf->maColorMask = ColorMask( 0x0000ff, 0x00ff00, 0xff0000 );
#else
                pBuf->maColorMask = ColorMask( 0xff0000, 0x00ff00, 0x0000ff );
#endif
                break;

            default:
                // this is an error case !!!!!
                nBitCount = 1;
                pBuf->mnFormat = BMP_FORMAT_1BIT_MSB_PAL;
                break;
        }
        if( m_aBitmap->isTopDown() )
            pBuf->mnFormat |= BMP_FORMAT_TOP_DOWN;

        B2IVector aSize = m_aBitmap->getSize();
        pBuf->mnWidth           = aSize.getX();
        pBuf->mnHeight          = aSize.getY();
        pBuf->mnScanlineSize    = m_aBitmap->getScanlineStride();
        pBuf->mnBitCount        = nBitCount;
        pBuf->mpBits            = (BYTE*)m_aBitmap->getBuffer().get();
        if( nBitCount <= 8 )
        {
            if( m_aBitmap->getScanlineFormat() == Format::EIGHT_BIT_GREY ||
                m_aBitmap->getScanlineFormat() == Format::FOUR_BIT_LSB_GREY ||
                m_aBitmap->getScanlineFormat() == Format::FOUR_BIT_MSB_GREY ||
                m_aBitmap->getScanlineFormat() == Format::ONE_BIT_LSB_GREY ||
                m_aBitmap->getScanlineFormat() == Format::ONE_BIT_MSB_GREY
                )
                pBuf->maPalette = Bitmap::GetGreyPalette( 1U << nBitCount );
            else
            {
                basebmp::PaletteMemorySharedVector aPalette = m_aBitmap->getPalette();
                if( aPalette.get() )
                {
                    unsigned int nColors = aPalette->size();
                    if( nColors > 0 )
                    {
                        pBuf->maPalette.SetEntryCount( nColors );
                        for( unsigned int i = 0; i < nColors; i++ )
                        {
                            const basebmp::Color& rCol = (*aPalette)[i];
                            pBuf->maPalette[i] = BitmapColor( rCol.getRed(), rCol.getGreen(), rCol.getBlue() );
                        }
                    }
                }
            }
        }
    }

    return pBuf;
}

void SvpSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly )
{
    if( !bReadOnly && pBuffer->maPalette.GetEntryCount() )
    {
        // palette might have changed, clone device (but recycle
        // memory)
        USHORT nBitCount = 0;
        switch( m_aBitmap->getScanlineFormat() )
        {
            case Format::ONE_BIT_MSB_GREY:
                // FALLTHROUGH intended
            case Format::ONE_BIT_MSB_PAL:
                // FALLTHROUGH intended
            case Format::ONE_BIT_LSB_GREY:
                // FALLTHROUGH intended
            case Format::ONE_BIT_LSB_PAL:
                nBitCount = 1;
                break;

            case Format::FOUR_BIT_MSB_GREY:
                // FALLTHROUGH intended
            case Format::FOUR_BIT_MSB_PAL:
                // FALLTHROUGH intended
            case Format::FOUR_BIT_LSB_GREY:
                // FALLTHROUGH intended
            case Format::FOUR_BIT_LSB_PAL:
                nBitCount = 4;
                break;

            case Format::EIGHT_BIT_PAL:
                // FALLTHROUGH intended
            case Format::EIGHT_BIT_GREY:
                nBitCount = 8;
                break;

            default:
                break;
        }

        if( nBitCount )
        {
            sal_uInt32 nEntries = 1U << nBitCount;

            boost::shared_ptr< std::vector<basebmp::Color> > pPal(
                new std::vector<basebmp::Color>( nEntries,
                                                 basebmp::Color(COL_WHITE)));
            const sal_uInt32 nColors = std::min(
                (sal_uInt32)pBuffer->maPalette.GetEntryCount(),
                nEntries);
            for( sal_uInt32 i = 0; i < nColors; i++ )
            {
                const BitmapColor& rCol = pBuffer->maPalette[i];
                (*pPal)[i] = basebmp::Color( rCol.GetRed(), rCol.GetGreen(), rCol.GetBlue() );
            }

            m_aBitmap = basebmp::createBitmapDevice( m_aBitmap->getSize(),
                                                     m_aBitmap->isTopDown(),
                                                     m_aBitmap->getScanlineFormat(),
                                                     m_aBitmap->getBuffer(),
                                                     pPal );
        }
    }

    delete pBuffer;
}

bool SvpSalBitmap::GetSystemData( BitmapSystemData& )
{
    return false;
}

<commit_msg>INTEGRATION: CWS changefileheader (1.3.148); FILE MERGED 2008/03/28 15:45:12 rt 1.3.148.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: svpbmp.cxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "svpbmp.hxx"

#include <basegfx/vector/b2ivector.hxx>
#include <basegfx/range/b2irange.hxx>
#include <basebmp/scanlineformats.hxx>
#include <basebmp/color.hxx>

#include <vcl/salbtype.hxx>
#include <vcl/bitmap.hxx>

using namespace basebmp;
using namespace basegfx;

SvpSalBitmap::~SvpSalBitmap()
{
}

bool SvpSalBitmap::Create( const Size& rSize,
                           USHORT nBitCount,
                           const BitmapPalette& rPalette )
{
    sal_uInt32 nFormat = SVP_DEFAULT_BITMAP_FORMAT;
    switch( nBitCount )
    {
        case 1: nFormat = Format::ONE_BIT_MSB_PAL; break;
        case 4: nFormat = Format::FOUR_BIT_MSB_PAL; break;
        case 8: nFormat = Format::EIGHT_BIT_PAL; break;
#ifdef OSL_BIGENDIAN
        case 16: nFormat = Format::SIXTEEN_BIT_MSB_TC_MASK; break;
#else
        case 16: nFormat = Format::SIXTEEN_BIT_LSB_TC_MASK; break;
#endif
        case 24: nFormat = Format::TWENTYFOUR_BIT_TC_MASK; break;
        case 32: nFormat = Format::THIRTYTWO_BIT_TC_MASK; break;
    }
    B2IVector aSize( rSize.Width(), rSize.Height() );
    if( aSize.getX() == 0 )
        aSize.setX( 1 );
    if( aSize.getY() == 0 )
        aSize.setY( 1 );
    if( nBitCount > 8 )
        m_aBitmap = createBitmapDevice( aSize, false, nFormat );
    else
    {
        // prepare palette
        unsigned int nEntries = 1U << nBitCount;
        std::vector<basebmp::Color>* pPalette =
            new std::vector<basebmp::Color>( nEntries, basebmp::Color(COL_WHITE) );
        unsigned int nColors = rPalette.GetEntryCount();
        for( unsigned int i = 0; i < nColors; i++ )
        {
            const BitmapColor& rCol = rPalette[i];
            (*pPalette)[i] = basebmp::Color( rCol.GetRed(), rCol.GetGreen(), rCol.GetBlue() );
        }
        m_aBitmap = createBitmapDevice( aSize, false, nFormat,
                                        basebmp::RawMemorySharedArray(),
                                        basebmp::PaletteMemorySharedVector( pPalette )
                                        );
    }
    return true;
}

bool SvpSalBitmap::Create( const SalBitmap& rSalBmp )
{
    const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBmp);
    const BitmapDeviceSharedPtr& rSrcBmp = rSrc.getBitmap();
    if( rSrcBmp.get() )
    {
        B2IVector aSize = rSrcBmp->getSize();
        m_aBitmap = cloneBitmapDevice( aSize, rSrcBmp );
        B2IRange aRect( 0, 0, aSize.getX(), aSize.getY() );
        m_aBitmap->drawBitmap( rSrcBmp, aRect, aRect, DrawMode_PAINT );
    }
    else
        m_aBitmap.reset();

    return true;
}

bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
                           SalGraphics* /*pGraphics*/ )
{
    return false;
}

bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
                           USHORT /*nNewBitCount*/ )
{
    return false;
}

void SvpSalBitmap::Destroy()
{
    m_aBitmap.reset();
}

Size SvpSalBitmap::GetSize() const
{
    Size aSize;
    if( m_aBitmap.get() )
    {
        B2IVector aVec( m_aBitmap->getSize() );
        aSize = Size( aVec.getX(), aVec.getY() );
    }

    return aSize;
}

USHORT SvpSalBitmap::GetBitCount() const
{
    USHORT nDepth = 0;
    if( m_aBitmap.get() )
        nDepth = getBitCountFromScanlineFormat( m_aBitmap->getScanlineFormat() );
    return nDepth;
}

BitmapBuffer* SvpSalBitmap::AcquireBuffer( bool )
{
    BitmapBuffer* pBuf = NULL;
    if( m_aBitmap.get() )
    {
        pBuf = new BitmapBuffer();
        USHORT nBitCount = 1;
        switch( m_aBitmap->getScanlineFormat() )
        {
            case Format::ONE_BIT_MSB_GREY:
            case Format::ONE_BIT_MSB_PAL:
                nBitCount = 1;
                pBuf->mnFormat = BMP_FORMAT_1BIT_MSB_PAL;
                break;
            case Format::ONE_BIT_LSB_GREY:
            case Format::ONE_BIT_LSB_PAL:
                nBitCount = 1;
                pBuf->mnFormat = BMP_FORMAT_1BIT_LSB_PAL;
                break;
            case Format::FOUR_BIT_MSB_GREY:
            case Format::FOUR_BIT_MSB_PAL:
                nBitCount = 4;
                pBuf->mnFormat = BMP_FORMAT_4BIT_MSN_PAL;
                break;
            case Format::FOUR_BIT_LSB_GREY:
            case Format::FOUR_BIT_LSB_PAL:
                nBitCount = 4;
                pBuf->mnFormat = BMP_FORMAT_4BIT_LSN_PAL;
                break;
            case Format::EIGHT_BIT_PAL:
                nBitCount = 8;
                pBuf->mnFormat = BMP_FORMAT_8BIT_PAL;
                break;
            case Format::EIGHT_BIT_GREY:
                nBitCount = 8;
                pBuf->mnFormat = BMP_FORMAT_8BIT_PAL;
                break;
            case Format::SIXTEEN_BIT_LSB_TC_MASK:
                nBitCount = 16;
                pBuf->mnFormat = BMP_FORMAT_16BIT_TC_LSB_MASK;
                pBuf->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f );
                break;
            case Format::SIXTEEN_BIT_MSB_TC_MASK:
                nBitCount = 16;
                pBuf->mnFormat = BMP_FORMAT_16BIT_TC_MSB_MASK;
                pBuf->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f );
                break;
            case Format::TWENTYFOUR_BIT_TC_MASK:
                nBitCount = 24;
                pBuf->mnFormat = BMP_FORMAT_24BIT_TC_BGR;
                break;
            case Format::THIRTYTWO_BIT_TC_MASK:
                nBitCount = 32;
                pBuf->mnFormat = BMP_FORMAT_32BIT_TC_MASK;
#ifdef OSL_BIGENDIAN
                pBuf->maColorMask = ColorMask( 0x0000ff, 0x00ff00, 0xff0000 );
#else
                pBuf->maColorMask = ColorMask( 0xff0000, 0x00ff00, 0x0000ff );
#endif
                break;

            default:
                // this is an error case !!!!!
                nBitCount = 1;
                pBuf->mnFormat = BMP_FORMAT_1BIT_MSB_PAL;
                break;
        }
        if( m_aBitmap->isTopDown() )
            pBuf->mnFormat |= BMP_FORMAT_TOP_DOWN;

        B2IVector aSize = m_aBitmap->getSize();
        pBuf->mnWidth           = aSize.getX();
        pBuf->mnHeight          = aSize.getY();
        pBuf->mnScanlineSize    = m_aBitmap->getScanlineStride();
        pBuf->mnBitCount        = nBitCount;
        pBuf->mpBits            = (BYTE*)m_aBitmap->getBuffer().get();
        if( nBitCount <= 8 )
        {
            if( m_aBitmap->getScanlineFormat() == Format::EIGHT_BIT_GREY ||
                m_aBitmap->getScanlineFormat() == Format::FOUR_BIT_LSB_GREY ||
                m_aBitmap->getScanlineFormat() == Format::FOUR_BIT_MSB_GREY ||
                m_aBitmap->getScanlineFormat() == Format::ONE_BIT_LSB_GREY ||
                m_aBitmap->getScanlineFormat() == Format::ONE_BIT_MSB_GREY
                )
                pBuf->maPalette = Bitmap::GetGreyPalette( 1U << nBitCount );
            else
            {
                basebmp::PaletteMemorySharedVector aPalette = m_aBitmap->getPalette();
                if( aPalette.get() )
                {
                    unsigned int nColors = aPalette->size();
                    if( nColors > 0 )
                    {
                        pBuf->maPalette.SetEntryCount( nColors );
                        for( unsigned int i = 0; i < nColors; i++ )
                        {
                            const basebmp::Color& rCol = (*aPalette)[i];
                            pBuf->maPalette[i] = BitmapColor( rCol.getRed(), rCol.getGreen(), rCol.getBlue() );
                        }
                    }
                }
            }
        }
    }

    return pBuf;
}

void SvpSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly )
{
    if( !bReadOnly && pBuffer->maPalette.GetEntryCount() )
    {
        // palette might have changed, clone device (but recycle
        // memory)
        USHORT nBitCount = 0;
        switch( m_aBitmap->getScanlineFormat() )
        {
            case Format::ONE_BIT_MSB_GREY:
                // FALLTHROUGH intended
            case Format::ONE_BIT_MSB_PAL:
                // FALLTHROUGH intended
            case Format::ONE_BIT_LSB_GREY:
                // FALLTHROUGH intended
            case Format::ONE_BIT_LSB_PAL:
                nBitCount = 1;
                break;

            case Format::FOUR_BIT_MSB_GREY:
                // FALLTHROUGH intended
            case Format::FOUR_BIT_MSB_PAL:
                // FALLTHROUGH intended
            case Format::FOUR_BIT_LSB_GREY:
                // FALLTHROUGH intended
            case Format::FOUR_BIT_LSB_PAL:
                nBitCount = 4;
                break;

            case Format::EIGHT_BIT_PAL:
                // FALLTHROUGH intended
            case Format::EIGHT_BIT_GREY:
                nBitCount = 8;
                break;

            default:
                break;
        }

        if( nBitCount )
        {
            sal_uInt32 nEntries = 1U << nBitCount;

            boost::shared_ptr< std::vector<basebmp::Color> > pPal(
                new std::vector<basebmp::Color>( nEntries,
                                                 basebmp::Color(COL_WHITE)));
            const sal_uInt32 nColors = std::min(
                (sal_uInt32)pBuffer->maPalette.GetEntryCount(),
                nEntries);
            for( sal_uInt32 i = 0; i < nColors; i++ )
            {
                const BitmapColor& rCol = pBuffer->maPalette[i];
                (*pPal)[i] = basebmp::Color( rCol.GetRed(), rCol.GetGreen(), rCol.GetBlue() );
            }

            m_aBitmap = basebmp::createBitmapDevice( m_aBitmap->getSize(),
                                                     m_aBitmap->isTopDown(),
                                                     m_aBitmap->getScanlineFormat(),
                                                     m_aBitmap->getBuffer(),
                                                     pPal );
        }
    }

    delete pBuffer;
}

bool SvpSalBitmap::GetSystemData( BitmapSystemData& )
{
    return false;
}

<|endoftext|>


<commit_before>#include "chrono_parallel/ChSystemParallel.h"
#include <omp.h>

using namespace chrono;

ChSystemParallelDVI::ChSystemParallelDVI(unsigned int max_objects)
      : ChSystemParallel(max_objects) {
   LCP_descriptor = new ChLcpSystemDescriptorParallelDVI();
   LCP_solver_speed = new ChLcpSolverParallelDVI();
   ((ChLcpSystemDescriptorParallelDVI*) LCP_descriptor)->data_container = data_manager;
   ((ChLcpSolverParallel*) LCP_solver_speed)->data_container = data_manager;

   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurA_normal");
   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurA_sliding");
   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurA_spinning");
   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurA_reduce");
   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurB_normal");
   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurB_sliding");
   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurB_spinning");

   data_manager->system_timer.AddTimer("ChSolverParallel_solverA");
   data_manager->system_timer.AddTimer("ChSolverParallel_solverB");
   data_manager->system_timer.AddTimer("ChSolverParallel_solverC");
   data_manager->system_timer.AddTimer("ChSolverParallel_solverD");
   data_manager->system_timer.AddTimer("ChSolverParallel_solverE");
   data_manager->system_timer.AddTimer("ChSolverParallel_solverF");
   data_manager->system_timer.AddTimer("ChSolverParallel_solverG");
   data_manager->system_timer.AddTimer("ChSolverParallel_Project");
   data_manager->system_timer.AddTimer("ChSolverParallel_Solve");

}

void ChSystemParallelDVI::LoadMaterialSurfaceData(ChSharedPtr<ChBody> newbody) {
   assert(typeid(*newbody.get_ptr()) == typeid(ChBody));

   ChSharedPtr<ChMaterialSurface>& mat = newbody->GetMaterialSurface();

   data_manager->host_data.fric_data.push_back(
   R3(mat->GetKfriction(), mat->GetRollingFriction(), mat->GetSpinningFriction()));
   data_manager->host_data.cohesion_data.push_back(mat->GetCohesion());
   data_manager->host_data.compliance_data.push_back(
   R4(mat->GetCompliance(), mat->GetComplianceT(), mat->GetComplianceRolling(), mat->GetComplianceSpinning()));
}

void ChSystemParallelDVI::UpdateBodies() {
   real3 *vel_pointer = data_manager->host_data.vel_data.data();
   real3 *omg_pointer = data_manager->host_data.omg_data.data();
   real3 *pos_pointer = data_manager->host_data.pos_data.data();
   real4 *rot_pointer = data_manager->host_data.rot_data.data();
   real3 *inr_pointer = data_manager->host_data.inr_data.data();
   real3 *frc_pointer = data_manager->host_data.frc_data.data();
   real3 *trq_pointer = data_manager->host_data.trq_data.data();
   bool *active_pointer = data_manager->host_data.active_data.data();
   bool *collide_pointer = data_manager->host_data.collide_data.data();
   real *mass_pointer = data_manager->host_data.mass_data.data();
   real3 *fric_pointer = data_manager->host_data.fric_data.data();
   real *cohesion_pointer = data_manager->host_data.cohesion_data.data();
   real4 *compliance_pointer = data_manager->host_data.compliance_data.data();
   real3 *lim_pointer = data_manager->host_data.lim_data.data();

#pragma omp parallel for
   for (int i = 0; i < bodylist.size(); i++) {
      bodylist[i]->UpdateTime(ChTime);
      //bodylist[i]->TrySleeping();			// See if the body can fall asleep; if so, put it to sleeping
      bodylist[i]->ClampSpeed();     // Apply limits (if in speed clamping mode) to speeds.
      bodylist[i]->ComputeGyro();     // Set the gyroscopic momentum.
      bodylist[i]->UpdateForces(ChTime);
      bodylist[i]->VariablesFbReset();
      bodylist[i]->VariablesFbLoadForces(GetStep());
      bodylist[i]->VariablesQbLoadSpeed();

      bodylist[i]->UpdateMarkers(ChTime);
      //because the loop is running in parallel, this cannot be run (not really needed anyways)
      //bodylist[i]->InjectVariables(*this->LCP_descriptor);

      ChMatrix33<> inertia = bodylist[i]->VariablesBody().GetBodyInvInertia();
      vel_pointer[i] = (R3(bodylist[i]->Variables().Get_qb().ElementN(0), bodylist[i]->Variables().Get_qb().ElementN(1), bodylist[i]->Variables().Get_qb().ElementN(2)));
      omg_pointer[i] = (R3(bodylist[i]->Variables().Get_qb().ElementN(3), bodylist[i]->Variables().Get_qb().ElementN(4), bodylist[i]->Variables().Get_qb().ElementN(5)));
      pos_pointer[i] = (R3(bodylist[i]->GetPos().x, bodylist[i]->GetPos().y, bodylist[i]->GetPos().z));
      rot_pointer[i] = (R4(bodylist[i]->GetRot().e0, bodylist[i]->GetRot().e1, bodylist[i]->GetRot().e2, bodylist[i]->GetRot().e3));
      inr_pointer[i] = (R3(inertia.GetElement(0, 0), inertia.GetElement(1, 1), inertia.GetElement(2, 2)));
      frc_pointer[i] = (R3(bodylist[i]->Variables().Get_fb().ElementN(0), bodylist[i]->Variables().Get_fb().ElementN(1), bodylist[i]->Variables().Get_fb().ElementN(2)));   //forces
      trq_pointer[i] = (R3(bodylist[i]->Variables().Get_fb().ElementN(3), bodylist[i]->Variables().Get_fb().ElementN(4), bodylist[i]->Variables().Get_fb().ElementN(5)));  //torques
      active_pointer[i] = bodylist[i]->IsActive();
      collide_pointer[i] = bodylist[i]->GetCollide();
      mass_pointer[i] = 1.0f / bodylist[i]->VariablesBody().GetBodyMass();
      fric_pointer[i] = R3(bodylist[i]->GetKfriction(), ((bodylist[i]))->GetMaterialSurface()->GetRollingFriction(), ((bodylist[i]))->GetMaterialSurface()->GetSpinningFriction());
      cohesion_pointer[i] = bodylist[i]->GetMaterialSurface()->GetCohesion();
      compliance_pointer[i] = R4(bodylist[i]->GetMaterialSurface()->GetCompliance(), bodylist[i]->GetMaterialSurface()->GetComplianceT(),
                                 bodylist[i]->GetMaterialSurface()->GetComplianceRolling(), bodylist[i]->GetMaterialSurface()->GetComplianceSpinning());
      lim_pointer[i] = (R3(bodylist[i]->GetLimitSpeed(), .05 / GetStep(), .05 / GetStep()));
      bodylist[i]->GetCollisionModel()->SyncPosition();
   }
}

static inline chrono::ChVector<real> ToChVector(const real3 &a) {
   return chrono::ChVector<real>(a.x, a.y, a.z);
}

void ChSystemParallelDVI::SolveSystem() {
   data_manager->system_timer.Reset();
   data_manager->system_timer.start("step");
   data_manager->system_timer.start("update");
   Setup();
   Update();
   data_manager->system_timer.stop("update");
   data_manager->system_timer.start("collision");
   collision_system->Run();
   collision_system->ReportContacts(this->contact_container);
   data_manager->system_timer.stop("collision");
   data_manager->system_timer.start("lcp");
   ((ChLcpSolverParallel *) (LCP_solver_speed))->RunTimeStep(GetStep());
   data_manager->system_timer.stop("lcp");
   data_manager->system_timer.stop("step");
}
void ChSystemParallelDVI::AssembleSystem() {

   collision_system->Run();
   collision_system->ReportContacts(this->contact_container);

   this->contact_container->BeginAddContact();
   chrono::collision::ChCollisionInfo icontact;
   for (int i = 0; i < data_manager->num_contacts; i++) {
      int2 cd_pair = data_manager->host_data.bids_rigid_rigid[i];
      icontact.modelA = bodylist[cd_pair.x]->GetCollisionModel();
      icontact.modelB = bodylist[cd_pair.y]->GetCollisionModel();
      icontact.vN = ToChVector(data_manager->host_data.norm_rigid_rigid[i]);
      icontact.vpA = ToChVector(data_manager->host_data.cpta_rigid_rigid[i] + data_manager->host_data.pos_data[cd_pair.x]);
      icontact.vpB = ToChVector(data_manager->host_data.cptb_rigid_rigid[i] + data_manager->host_data.pos_data[cd_pair.y]);
      icontact.distance = data_manager->host_data.dpth_rigid_rigid[i];
      this->contact_container->AddContact(icontact);
   }
   this->contact_container->EndAddContact();

   {
      std::list<ChLink*>::iterator iterlink = linklist.begin();
      while (iterlink != linklist.end()) {
         (*iterlink)->ConstraintsBiReset();
         iterlink++;
      }
      std::vector<ChBody*>::iterator ibody = bodylist.begin();
      while (ibody != bodylist.end()) {
         (*ibody)->VariablesFbReset();
         ibody++;
      }
      this->contact_container->ConstraintsBiReset();
   }

   LCPprepare_load(true,                  // Cq,
         true,                            // adds [M]*v_old to the known vector
         step,                            // f*dt
         step * step,                     // dt^2*K  (nb only non-Schur based solvers support K matrix blocks)
         step,                            // dt*R   (nb only non-Schur based solvers support R matrix blocks)
         1.0,                             // M (for FEM with non-lumped masses, add their mass-matrixes)
         1.0,                             // Ct   (needed, for rheonomic motors)
         1.0 / step,                      // C/dt
         max_penetration_recovery_speed,  // vlim, max penetrations recovery speed (positive for exiting)
         true                             // do above max. clamping on -C/dt
         );

   this->LCP_descriptor->BeginInsertion();
   for (int i = 0; i < bodylist.size(); i++) {
      bodylist[i]->InjectVariables(*this->LCP_descriptor);
   }
   std::list<ChLink *>::iterator it;
   for (it = linklist.begin(); it != linklist.end(); it++) {
      (*it)->InjectConstraints(*this->LCP_descriptor);
   }
   this->contact_container->InjectConstraints(*this->LCP_descriptor);
   this->LCP_descriptor->EndInsertion();

}

<commit_msg>Update function needs to be run before assembling everything otherwise the results will be different than what chrono and chrono-parallel report<commit_after>#include "chrono_parallel/ChSystemParallel.h"
#include <omp.h>

using namespace chrono;

ChSystemParallelDVI::ChSystemParallelDVI(unsigned int max_objects)
      : ChSystemParallel(max_objects) {
   LCP_descriptor = new ChLcpSystemDescriptorParallelDVI();
   LCP_solver_speed = new ChLcpSolverParallelDVI();
   ((ChLcpSystemDescriptorParallelDVI*) LCP_descriptor)->data_container = data_manager;
   ((ChLcpSolverParallel*) LCP_solver_speed)->data_container = data_manager;

   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurA_normal");
   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurA_sliding");
   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurA_spinning");
   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurA_reduce");
   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurB_normal");
   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurB_sliding");
   data_manager->system_timer.AddTimer("ChConstraintRigidRigid_shurB_spinning");

   data_manager->system_timer.AddTimer("ChSolverParallel_solverA");
   data_manager->system_timer.AddTimer("ChSolverParallel_solverB");
   data_manager->system_timer.AddTimer("ChSolverParallel_solverC");
   data_manager->system_timer.AddTimer("ChSolverParallel_solverD");
   data_manager->system_timer.AddTimer("ChSolverParallel_solverE");
   data_manager->system_timer.AddTimer("ChSolverParallel_solverF");
   data_manager->system_timer.AddTimer("ChSolverParallel_solverG");
   data_manager->system_timer.AddTimer("ChSolverParallel_Project");
   data_manager->system_timer.AddTimer("ChSolverParallel_Solve");

}

void ChSystemParallelDVI::LoadMaterialSurfaceData(ChSharedPtr<ChBody> newbody) {
   assert(typeid(*newbody.get_ptr()) == typeid(ChBody));

   ChSharedPtr<ChMaterialSurface>& mat = newbody->GetMaterialSurface();

   data_manager->host_data.fric_data.push_back(
   R3(mat->GetKfriction(), mat->GetRollingFriction(), mat->GetSpinningFriction()));
   data_manager->host_data.cohesion_data.push_back(mat->GetCohesion());
   data_manager->host_data.compliance_data.push_back(
   R4(mat->GetCompliance(), mat->GetComplianceT(), mat->GetComplianceRolling(), mat->GetComplianceSpinning()));
}

void ChSystemParallelDVI::UpdateBodies() {
   real3 *vel_pointer = data_manager->host_data.vel_data.data();
   real3 *omg_pointer = data_manager->host_data.omg_data.data();
   real3 *pos_pointer = data_manager->host_data.pos_data.data();
   real4 *rot_pointer = data_manager->host_data.rot_data.data();
   real3 *inr_pointer = data_manager->host_data.inr_data.data();
   real3 *frc_pointer = data_manager->host_data.frc_data.data();
   real3 *trq_pointer = data_manager->host_data.trq_data.data();
   bool *active_pointer = data_manager->host_data.active_data.data();
   bool *collide_pointer = data_manager->host_data.collide_data.data();
   real *mass_pointer = data_manager->host_data.mass_data.data();
   real3 *fric_pointer = data_manager->host_data.fric_data.data();
   real *cohesion_pointer = data_manager->host_data.cohesion_data.data();
   real4 *compliance_pointer = data_manager->host_data.compliance_data.data();
   real3 *lim_pointer = data_manager->host_data.lim_data.data();

#pragma omp parallel for
   for (int i = 0; i < bodylist.size(); i++) {
      bodylist[i]->UpdateTime(ChTime);
      //bodylist[i]->TrySleeping();			// See if the body can fall asleep; if so, put it to sleeping
      bodylist[i]->ClampSpeed();     // Apply limits (if in speed clamping mode) to speeds.
      bodylist[i]->ComputeGyro();     // Set the gyroscopic momentum.
      bodylist[i]->UpdateForces(ChTime);
      bodylist[i]->VariablesFbReset();
      bodylist[i]->VariablesFbLoadForces(GetStep());
      bodylist[i]->VariablesQbLoadSpeed();

      bodylist[i]->UpdateMarkers(ChTime);
      //because the loop is running in parallel, this cannot be run (not really needed anyways)
      //bodylist[i]->InjectVariables(*this->LCP_descriptor);

      ChMatrix33<> inertia = bodylist[i]->VariablesBody().GetBodyInvInertia();
      vel_pointer[i] = (R3(bodylist[i]->Variables().Get_qb().ElementN(0), bodylist[i]->Variables().Get_qb().ElementN(1), bodylist[i]->Variables().Get_qb().ElementN(2)));
      omg_pointer[i] = (R3(bodylist[i]->Variables().Get_qb().ElementN(3), bodylist[i]->Variables().Get_qb().ElementN(4), bodylist[i]->Variables().Get_qb().ElementN(5)));
      pos_pointer[i] = (R3(bodylist[i]->GetPos().x, bodylist[i]->GetPos().y, bodylist[i]->GetPos().z));
      rot_pointer[i] = (R4(bodylist[i]->GetRot().e0, bodylist[i]->GetRot().e1, bodylist[i]->GetRot().e2, bodylist[i]->GetRot().e3));
      inr_pointer[i] = (R3(inertia.GetElement(0, 0), inertia.GetElement(1, 1), inertia.GetElement(2, 2)));
      frc_pointer[i] = (R3(bodylist[i]->Variables().Get_fb().ElementN(0), bodylist[i]->Variables().Get_fb().ElementN(1), bodylist[i]->Variables().Get_fb().ElementN(2)));   //forces
      trq_pointer[i] = (R3(bodylist[i]->Variables().Get_fb().ElementN(3), bodylist[i]->Variables().Get_fb().ElementN(4), bodylist[i]->Variables().Get_fb().ElementN(5)));  //torques
      active_pointer[i] = bodylist[i]->IsActive();
      collide_pointer[i] = bodylist[i]->GetCollide();
      mass_pointer[i] = 1.0f / bodylist[i]->VariablesBody().GetBodyMass();
      fric_pointer[i] = R3(bodylist[i]->GetKfriction(), ((bodylist[i]))->GetMaterialSurface()->GetRollingFriction(), ((bodylist[i]))->GetMaterialSurface()->GetSpinningFriction());
      cohesion_pointer[i] = bodylist[i]->GetMaterialSurface()->GetCohesion();
      compliance_pointer[i] = R4(bodylist[i]->GetMaterialSurface()->GetCompliance(), bodylist[i]->GetMaterialSurface()->GetComplianceT(),
                                 bodylist[i]->GetMaterialSurface()->GetComplianceRolling(), bodylist[i]->GetMaterialSurface()->GetComplianceSpinning());
      lim_pointer[i] = (R3(bodylist[i]->GetLimitSpeed(), .05 / GetStep(), .05 / GetStep()));
      bodylist[i]->GetCollisionModel()->SyncPosition();
   }
}

static inline chrono::ChVector<real> ToChVector(const real3 &a) {
   return chrono::ChVector<real>(a.x, a.y, a.z);
}

void ChSystemParallelDVI::SolveSystem() {
   data_manager->system_timer.Reset();
   data_manager->system_timer.start("step");
   data_manager->system_timer.start("update");
   Setup();
   Update();
   data_manager->system_timer.stop("update");
   data_manager->system_timer.start("collision");
   collision_system->Run();
   collision_system->ReportContacts(this->contact_container);
   data_manager->system_timer.stop("collision");
   data_manager->system_timer.start("lcp");
   ((ChLcpSolverParallel *) (LCP_solver_speed))->RunTimeStep(GetStep());
   data_manager->system_timer.stop("lcp");
   data_manager->system_timer.stop("step");
}
void ChSystemParallelDVI::AssembleSystem() {
   Setup();

   collision_system->Run();
   collision_system->ReportContacts(this->contact_container);
   ChSystem::Update();
   this->contact_container->BeginAddContact();
   chrono::collision::ChCollisionInfo icontact;
   for (int i = 0; i < data_manager->num_contacts; i++) {
      int2 cd_pair = data_manager->host_data.bids_rigid_rigid[i];
      icontact.modelA = bodylist[cd_pair.x]->GetCollisionModel();
      icontact.modelB = bodylist[cd_pair.y]->GetCollisionModel();
      icontact.vN = ToChVector(data_manager->host_data.norm_rigid_rigid[i]);
      icontact.vpA = ToChVector(data_manager->host_data.cpta_rigid_rigid[i] + data_manager->host_data.pos_data[cd_pair.x]);
      icontact.vpB = ToChVector(data_manager->host_data.cptb_rigid_rigid[i] + data_manager->host_data.pos_data[cd_pair.y]);
      icontact.distance = data_manager->host_data.dpth_rigid_rigid[i];
      this->contact_container->AddContact(icontact);
   }
   this->contact_container->EndAddContact();

   {
      std::list<ChLink*>::iterator iterlink = linklist.begin();
      while (iterlink != linklist.end()) {
         (*iterlink)->ConstraintsBiReset();
         iterlink++;
      }
      std::vector<ChBody*>::iterator ibody = bodylist.begin();
      while (ibody != bodylist.end()) {
         (*ibody)->VariablesFbReset();
         ibody++;
      }
      this->contact_container->ConstraintsBiReset();
   }

   LCPprepare_load(true,                  // Cq,
         true,                            // adds [M]*v_old to the known vector
         step,                            // f*dt
         step * step,                     // dt^2*K  (nb only non-Schur based solvers support K matrix blocks)
         step,                            // dt*R   (nb only non-Schur based solvers support R matrix blocks)
         1.0,                             // M (for FEM with non-lumped masses, add their mass-matrixes)
         1.0,                             // Ct   (needed, for rheonomic motors)
         1.0 / step,                      // C/dt
         max_penetration_recovery_speed,  // vlim, max penetrations recovery speed (positive for exiting)
         true                             // do above max. clamping on -C/dt
         );

   this->LCP_descriptor->BeginInsertion();
   for (int i = 0; i < bodylist.size(); i++) {
      bodylist[i]->InjectVariables(*this->LCP_descriptor);
   }
   std::list<ChLink *>::iterator it;
   for (it = linklist.begin(); it != linklist.end(); it++) {
      (*it)->InjectConstraints(*this->LCP_descriptor);
   }
   this->contact_container->InjectConstraints(*this->LCP_descriptor);
   this->LCP_descriptor->EndInsertion();

}

<|endoftext|>