<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 "otbImageToLuminanceImageFilter.h"
#include "otbLuminanceToReflectanceImageFilter.h"
#include "otbReflectanceToSurfaceReflectanceImageFilter.h"
#include "otbMultiplyByScalarImageFilter.h"

namespace otb
{

enum
{
  Level_TOA,
  Level_TOC
};

enum
{
  Aerosol_NoAerosol,
  Aerosol_Continental,
  Aerosol_Maritime,
  Aerosol_Urban,
  Aerosol_Desertic,
};

namespace Wrapper
{

class OpticalCalibration : public Application
{

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

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

  itkTypeMacro(OpticalCalibration, Application);

  typedef ImageToLuminanceImageFilter<UInt16VectorImageType,
                                      DoubleVectorImageType>              ImageToLuminanceImageFilterType;

  typedef LuminanceToReflectanceImageFilter<DoubleVectorImageType,
                                            DoubleVectorImageType>        LuminanceToReflectanceImageFilterType;

  typedef otb::MultiplyByScalarImageFilter<DoubleVectorImageType,
                                           DoubleVectorImageType>         ScaleFilterType;

  typedef ReflectanceToSurfaceReflectanceImageFilter<DoubleVectorImageType,
                                                     DoubleVectorImageType>         ReflectanceToSurfaceReflectanceImageFilterType;
  typedef ReflectanceToSurfaceReflectanceImageFilterType::FilterFunctionValuesType  FilterFunctionValuesType;
  typedef FilterFunctionValuesType::ValuesVectorType                                ValuesVectorType;
  typedef AtmosphericCorrectionParameters                                           AtmosphericCorrectionParametersType;
  typedef AtmosphericCorrectionParametersType::AerosolModelType                     AerosolModelType;

private:
  OpticalCalibration()
  {
    SetName("OpticalCalibration");
    SetDescription("Perform optical calibration TOA/TOC (Top Of Atmosphere/Top Of Canopy). Supported sensors: QuickBird, Ikonos, WorldView2, Formosat, Spot5");
    // Documentation
    SetDocName("Optical calibration application");
    SetDocLongDescription("The application allows to convert pixel values from DN (for Digital Numbers) to physically interpretable and comparable values.Calibrated values are called surface reflectivity and its values lie in the range [0, 1].\nThe first level is called Top Of Atmosphere (TOA) reflectivity. It takes into account the sensor gain, sensor spectral response and the solar illumination.\nThe second level is called Top Of Canopy (TOC) reflectivity. In addition to sensor gain and solar illumination, it takes into account the optical thickness of the atmosphere, the atmospheric pressure, the water vapor amount, the ozone amount, as well as the composition and amount of aerosol gasses.\nIt is also possible to indicate an AERONET file which contains atmospheric parameters (version 1 and version 2 of Aeronet file are supported.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("The OTB CookBook");

    AddDocTag(Tags::Calibration);

}

  void DoCreateParameters()
  {
    AddParameter(ParameterType_InputImage,  "in",  "Input Image Filename");

    AddParameter(ParameterType_OutputImage, "out", "Output Image Filename");
    SetParameterDescription("out","Calibrated Image Filename");

    AddParameter(ParameterType_RAM, "ram", "Available RAM");
    SetDefaultParameterInt("ram", 256);
    MandatoryOff("ram");

    AddParameter(ParameterType_Choice,   "level", "Calibration Level");
    AddChoice("level.toa",     "TOA : Top Of Atmosphere");
    AddChoice("level.toc",     "TOC : Top Of Canopy (EXPERIMENTAL)");
    SetParameterString("level", "toa");

    AddParameter(ParameterType_Empty, "milli", "Convert to milli reflectance");
    SetParameterDescription("milli", "Output milli-reflectance instead of reflectance.\n"
                                     "This allows to put save the image in integer pixel type (in the range [0, 1000]  instead of floating point in the range [0, 1].");
    DisableParameter("milli");
    MandatoryOff("milli");

    AddParameter(ParameterType_Filename,   "rsr", "Relative Spectral Response File");
    std::ostringstream oss;
    oss << "Sensor relative spectral response file"<<std::endl;
    oss << "By default the application gets these informations in the metadata";
    SetParameterDescription("rsr", oss.str());
    MandatoryOff("rsr");

    AddParameter(ParameterType_Group,"atmo","Atmospheric parameters");
    SetParameterDescription("atmo","This group allows to set the atmospheric parameters.");
    AddParameter(ParameterType_Choice,   "atmo.aerosol", "Aerosol Model");
    AddChoice("atmo.aerosol.noaersol",    "No Aerosol Model");
    AddChoice("atmo.aerosol.continental", "Continental");
    AddChoice("atmo.aerosol.maritime",    "Maritime");
    AddChoice("atmo.aerosol.urban",       "Urban");
    AddChoice("atmo.aerosol.desertic",    "Desertic");

    AddParameter(ParameterType_Float, "atmo.oz",   "Ozone Amount");
    AddParameter(ParameterType_Float, "atmo.wa",   "Water Vapor Amount");
    AddParameter(ParameterType_Float, "atmo.pressure", "Atmospheric Pressure");
    AddParameter(ParameterType_Float, "atmo.opt",  "Aerosol Optical Thickness");

    SetDefaultParameterFloat("atmo.oz", 0.);
    SetDefaultParameterFloat("atmo.wa",  2.5);
    SetDefaultParameterFloat("atmo.pressure", 1030.);

    SetDefaultParameterFloat("atmo.opt", 0.2);
    MandatoryOff("atmo.oz");
    MandatoryOff("atmo.wa");
    MandatoryOff("atmo.pressure");
    MandatoryOff("atmo.opt");

    AddParameter(ParameterType_Filename,   "atmo.aeronet", "Aeronet File");
    SetParameterDescription("atmo.aeronet","Aeronet file containing atmospheric parameters");
    MandatoryOff("atmo.aeronet");

   // Doc example parameter settings
    SetDocExampleParameterValue("in", "WV2_MUL_ROI_1000_100.tif");
    SetDocExampleParameterValue("level", "toa");
    SetDocExampleParameterValue("out", "OpticalCalibration.tif");
  }

  void DoUpdateParameters()
  {
    // Nothing to update
  }

  void DoExecute()
  {
    UInt16VectorImageType::Pointer inImage = GetParameterUInt16VectorImage("in");

    //Check if valid metadata informations are available to compute ImageToLuminance and LuminanceToReflectance
    itk::MetaDataDictionary             dict = inImage->GetMetaDataDictionary();
    OpticalImageMetadataInterface::Pointer lImageMetadataInterface = OpticalImageMetadataInterfaceFactory::CreateIMI(dict);

    // Test if needed data are available : an exception will be thrown
    // if one the following Get* return failure. the exception is then
    // caught in the Wrapper::Application class which redirect it to
    // the logger
    // ImageToLuminance
    lImageMetadataInterface->GetPhysicalGain();
    lImageMetadataInterface->GetPhysicalBias();

    // LuminanceToReflectance
    lImageMetadataInterface->GetDay();
    lImageMetadataInterface->GetMonth();

    lImageMetadataInterface->GetSolarIrradiance();
    lImageMetadataInterface->GetSunElevation();

    m_ImageToLuminanceFilter                = ImageToLuminanceImageFilterType::New();
    m_LuminanceToReflectanceFilter          = LuminanceToReflectanceImageFilterType::New();
    m_ReflectanceToSurfaceReflectanceFilter = ReflectanceToSurfaceReflectanceImageFilterType::New();

    m_ImageToLuminanceFilter->SetInput(inImage);
    m_LuminanceToReflectanceFilter->SetInput(m_ImageToLuminanceFilter->GetOutput());
    m_ReflectanceToSurfaceReflectanceFilter->SetInput(m_LuminanceToReflectanceFilter->GetOutput());

    m_ScaleFilter = ScaleFilterType::New();
    m_ScaleFilter->InPlaceOn();

    switch ( GetParameterInt("level") )
      {
      case Level_TOA:
      {
      m_LuminanceToReflectanceFilter->UpdateOutputInformation();
      m_ScaleFilter->SetInput(m_LuminanceToReflectanceFilter->GetOutput());
      }
      break;
      case Level_TOC:
      {
      m_AtmosphericParam = m_ReflectanceToSurfaceReflectanceFilter->GetCorrectionParameters();
      //AerosolModelType aeroMod = AtmosphericCorrectionParametersType::NO_AEROSOL;

      switch ( GetParameterInt("atmo.aerosol") )
        {
        case Aerosol_Desertic:
        {
        // Aerosol_Desertic correspond to 4 in the enum but actually in
        // the class atmosphericParam it is known as parameter 5
        m_AtmosphericParam->SetAerosolModel(static_cast<AerosolModelType>(5));
        }
        break;
        default:
        {
        m_AtmosphericParam->SetAerosolModel(static_cast<AerosolModelType>(GetParameterInt("atmo.aerosol")));
        }
        break;
        }
      // Set the atmospheric param
      m_AtmosphericParam->SetOzoneAmount(GetParameterFloat("atmo.oz"));
      m_AtmosphericParam->SetWaterVaporAmount(GetParameterFloat("atmo.wa"));
      m_AtmosphericParam->SetAtmosphericPressure(GetParameterFloat("atmo.pressure"));
      m_AtmosphericParam->SetAerosolOptical(GetParameterFloat("atmo.opt"));

      // Relative Spectral Response File
      if (IsParameterEnabled("rsr"))
        {
        m_ReflectanceToSurfaceReflectanceFilter->SetFilterFunctionValuesFileName(GetParameterString("rsr"));
        }
      else
        {
        m_ReflectanceToSurfaceReflectanceFilter->SetFilterFunctionCoef(lImageMetadataInterface->GetSpectralSensitivity());
        }

      // Aeronet file
      if (IsParameterEnabled("atmo.aeronet"))
        {
        m_ReflectanceToSurfaceReflectanceFilter->SetAeronetFileName(GetParameterString("atmo.aeronet"));
        }

      //
      AtmosphericRadiativeTerms::Pointer radTerms = AtmosphericRadiativeTerms::New();
      radTerms->ValuesInitialization(inImage->GetNumberOfComponentsPerPixel());
      m_ReflectanceToSurfaceReflectanceFilter->SetAtmosphericRadiativeTerms(radTerms);
      m_ReflectanceToSurfaceReflectanceFilter->SetIsSetAtmosphericRadiativeTerms(true);
      m_ReflectanceToSurfaceReflectanceFilter->GenerateAtmosphericRadiativeTerms();
      m_ReflectanceToSurfaceReflectanceFilter->GenerateParameters();
      m_ReflectanceToSurfaceReflectanceFilter->SetUseGenerateParameters(false);

      //rescale the surface reflectance in milli-reflectance
      m_ReflectanceToSurfaceReflectanceFilter->UpdateOutputInformation();
      m_ScaleFilter->SetInput(m_ReflectanceToSurfaceReflectanceFilter->GetOutput());
      }
      break;
      }

    // Output Image
    const double scale = IsParameterEnabled("milli") ? 1000.0 : 1.0;
    m_ScaleFilter->SetCoef(scale);

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

  ImageToLuminanceImageFilterType ::Pointer               m_ImageToLuminanceFilter;
  LuminanceToReflectanceImageFilterType::Pointer          m_LuminanceToReflectanceFilter;
  ReflectanceToSurfaceReflectanceImageFilterType::Pointer m_ReflectanceToSurfaceReflectanceFilter;
  ScaleFilterType::Pointer                                m_ScaleFilter;
  AtmosphericCorrectionParametersType::Pointer            m_AtmosphericParam;
};

}// namespace Wrapper
} // namespace otb

OTB_APPLICATION_EXPORT(otb::Wrapper::OpticalCalibration)

<commit_msg>STY:remove end of lines<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 "otbImageToLuminanceImageFilter.h"
#include "otbLuminanceToReflectanceImageFilter.h"
#include "otbReflectanceToSurfaceReflectanceImageFilter.h"
#include "otbMultiplyByScalarImageFilter.h"

namespace otb
{

enum
{
  Level_TOA,
  Level_TOC
};

enum
{
  Aerosol_NoAerosol,
  Aerosol_Continental,
  Aerosol_Maritime,
  Aerosol_Urban,
  Aerosol_Desertic,
};

namespace Wrapper
{

class OpticalCalibration : public Application
{

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

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

  itkTypeMacro(OpticalCalibration, Application);

  typedef ImageToLuminanceImageFilter<UInt16VectorImageType,
                                      DoubleVectorImageType>              ImageToLuminanceImageFilterType;

  typedef LuminanceToReflectanceImageFilter<DoubleVectorImageType,
                                            DoubleVectorImageType>        LuminanceToReflectanceImageFilterType;

  typedef otb::MultiplyByScalarImageFilter<DoubleVectorImageType,
                                           DoubleVectorImageType>         ScaleFilterType;

  typedef ReflectanceToSurfaceReflectanceImageFilter<DoubleVectorImageType,
                                                     DoubleVectorImageType>         ReflectanceToSurfaceReflectanceImageFilterType;
  typedef ReflectanceToSurfaceReflectanceImageFilterType::FilterFunctionValuesType  FilterFunctionValuesType;
  typedef FilterFunctionValuesType::ValuesVectorType                                ValuesVectorType;
  typedef AtmosphericCorrectionParameters                                           AtmosphericCorrectionParametersType;
  typedef AtmosphericCorrectionParametersType::AerosolModelType                     AerosolModelType;

private:
  OpticalCalibration()
  {
    SetName("OpticalCalibration");
    SetDescription("Perform optical calibration TOA/TOC (Top Of Atmosphere/Top Of Canopy). Supported sensors: QuickBird, Ikonos, WorldView2, Formosat, Spot5");
    // Documentation
    SetDocName("Optical calibration application");
    SetDocLongDescription("The application allows to convert pixel values from DN (for Digital Numbers) to physically interpretable and comparable values.Calibrated values are called surface reflectivity and its values lie in the range [0, 1].\nThe first level is called Top Of Atmosphere (TOA) reflectivity. It takes into account the sensor gain, sensor spectral response and the solar illumination.\nThe second level is called Top Of Canopy (TOC) reflectivity. In addition to sensor gain and solar illumination, it takes into account the optical thickness of the atmosphere, the atmospheric pressure, the water vapor amount, the ozone amount, as well as the composition and amount of aerosol gasses.\nIt is also possible to indicate an AERONET file which contains atmospheric parameters (version 1 and version 2 of Aeronet file are supported.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("The OTB CookBook");

    AddDocTag(Tags::Calibration);

}

  void DoCreateParameters()
  {
    AddParameter(ParameterType_InputImage,  "in",  "Input Image Filename");

    AddParameter(ParameterType_OutputImage, "out", "Output Image Filename");
    SetParameterDescription("out","Calibrated Image Filename");

    AddParameter(ParameterType_RAM, "ram", "Available RAM");
    SetDefaultParameterInt("ram", 256);
    MandatoryOff("ram");

    AddParameter(ParameterType_Choice,   "level", "Calibration Level");
    AddChoice("level.toa",     "TOA : Top Of Atmosphere");
    AddChoice("level.toc",     "TOC : Top Of Canopy (EXPERIMENTAL)");
    SetParameterString("level", "toa");

    AddParameter(ParameterType_Empty, "milli", "Convert to milli reflectance");
    SetParameterDescription("milli", "Output milli-reflectance instead of reflectance.\n"
                                     "This allows to put save the image in integer pixel type (in the range [0, 1000]  instead of floating point in the range [0, 1].");
    DisableParameter("milli");
    MandatoryOff("milli");

    AddParameter(ParameterType_Filename,   "rsr", "Relative Spectral Response File");
    std::ostringstream oss;
    oss << "Sensor relative spectral response file"<<std::endl;
    oss << "By default the application gets these informations in the metadata";
    SetParameterDescription("rsr", oss.str());
    MandatoryOff("rsr");

    AddParameter(ParameterType_Group,"atmo","Atmospheric parameters");
    SetParameterDescription("atmo","This group allows to set the atmospheric parameters.");
    AddParameter(ParameterType_Choice,   "atmo.aerosol", "Aerosol Model");
    AddChoice("atmo.aerosol.noaersol",    "No Aerosol Model");
    AddChoice("atmo.aerosol.continental", "Continental");
    AddChoice("atmo.aerosol.maritime",    "Maritime");
    AddChoice("atmo.aerosol.urban",       "Urban");
    AddChoice("atmo.aerosol.desertic",    "Desertic");

    AddParameter(ParameterType_Float, "atmo.oz",   "Ozone Amount");
    AddParameter(ParameterType_Float, "atmo.wa",   "Water Vapor Amount");
    AddParameter(ParameterType_Float, "atmo.pressure", "Atmospheric Pressure");
    AddParameter(ParameterType_Float, "atmo.opt",  "Aerosol Optical Thickness");

    SetDefaultParameterFloat("atmo.oz", 0.);
    SetDefaultParameterFloat("atmo.wa",  2.5);
    SetDefaultParameterFloat("atmo.pressure", 1030.);

    SetDefaultParameterFloat("atmo.opt", 0.2);
    MandatoryOff("atmo.oz");
    MandatoryOff("atmo.wa");
    MandatoryOff("atmo.pressure");
    MandatoryOff("atmo.opt");

    AddParameter(ParameterType_Filename,   "atmo.aeronet", "Aeronet File");
    SetParameterDescription("atmo.aeronet","Aeronet file containing atmospheric parameters");
    MandatoryOff("atmo.aeronet");

   // Doc example parameter settings
    SetDocExampleParameterValue("in", "WV2_MUL_ROI_1000_100.tif");
    SetDocExampleParameterValue("level", "toa");
    SetDocExampleParameterValue("out", "OpticalCalibration.tif");
  }

  void DoUpdateParameters()
  {
    // Nothing to update
  }

  void DoExecute()
  {
    UInt16VectorImageType::Pointer inImage = GetParameterUInt16VectorImage("in");

    //Check if valid metadata informations are available to compute ImageToLuminance and LuminanceToReflectance
    itk::MetaDataDictionary             dict = inImage->GetMetaDataDictionary();
    OpticalImageMetadataInterface::Pointer lImageMetadataInterface = OpticalImageMetadataInterfaceFactory::CreateIMI(dict);

    // Test if needed data are available : an exception will be thrown
    // if one the following Get* return failure. the exception is then
    // caught in the Wrapper::Application class which redirect it to
    // the logger
    // ImageToLuminance
    lImageMetadataInterface->GetPhysicalGain();
    lImageMetadataInterface->GetPhysicalBias();

    // LuminanceToReflectance
    lImageMetadataInterface->GetDay();
    lImageMetadataInterface->GetMonth();

    lImageMetadataInterface->GetSolarIrradiance();
    lImageMetadataInterface->GetSunElevation();

    m_ImageToLuminanceFilter                = ImageToLuminanceImageFilterType::New();
    m_LuminanceToReflectanceFilter          = LuminanceToReflectanceImageFilterType::New();
    m_ReflectanceToSurfaceReflectanceFilter = ReflectanceToSurfaceReflectanceImageFilterType::New();

    m_ImageToLuminanceFilter->SetInput(inImage);
    m_LuminanceToReflectanceFilter->SetInput(m_ImageToLuminanceFilter->GetOutput());
    m_ReflectanceToSurfaceReflectanceFilter->SetInput(m_LuminanceToReflectanceFilter->GetOutput());

    m_ScaleFilter = ScaleFilterType::New();
    m_ScaleFilter->InPlaceOn();

    switch ( GetParameterInt("level") )
      {
      case Level_TOA:
      {
      m_LuminanceToReflectanceFilter->UpdateOutputInformation();
      m_ScaleFilter->SetInput(m_LuminanceToReflectanceFilter->GetOutput());
      }
      break;
      case Level_TOC:
      {
      m_AtmosphericParam = m_ReflectanceToSurfaceReflectanceFilter->GetCorrectionParameters();
      //AerosolModelType aeroMod = AtmosphericCorrectionParametersType::NO_AEROSOL;

      switch ( GetParameterInt("atmo.aerosol") )
        {
        case Aerosol_Desertic:
        {
        // Aerosol_Desertic correspond to 4 in the enum but actually in
        // the class atmosphericParam it is known as parameter 5
        m_AtmosphericParam->SetAerosolModel(static_cast<AerosolModelType>(5));
        }
        break;
        default:
        {
        m_AtmosphericParam->SetAerosolModel(static_cast<AerosolModelType>(GetParameterInt("atmo.aerosol")));
        }
        break;
        }
      // Set the atmospheric param
      m_AtmosphericParam->SetOzoneAmount(GetParameterFloat("atmo.oz"));
      m_AtmosphericParam->SetWaterVaporAmount(GetParameterFloat("atmo.wa"));
      m_AtmosphericParam->SetAtmosphericPressure(GetParameterFloat("atmo.pressure"));
      m_AtmosphericParam->SetAerosolOptical(GetParameterFloat("atmo.opt"));

      // Relative Spectral Response File
      if (IsParameterEnabled("rsr"))
        {
        m_ReflectanceToSurfaceReflectanceFilter->SetFilterFunctionValuesFileName(GetParameterString("rsr"));
        }
      else
        {
        m_ReflectanceToSurfaceReflectanceFilter->SetFilterFunctionCoef(lImageMetadataInterface->GetSpectralSensitivity());
        }

      // Aeronet file
      if (IsParameterEnabled("atmo.aeronet"))
        {
        m_ReflectanceToSurfaceReflectanceFilter->SetAeronetFileName(GetParameterString("atmo.aeronet"));
        }

      //
      AtmosphericRadiativeTerms::Pointer radTerms = AtmosphericRadiativeTerms::New();
      radTerms->ValuesInitialization(inImage->GetNumberOfComponentsPerPixel());
      m_ReflectanceToSurfaceReflectanceFilter->SetAtmosphericRadiativeTerms(radTerms);
      m_ReflectanceToSurfaceReflectanceFilter->SetIsSetAtmosphericRadiativeTerms(true);
      m_ReflectanceToSurfaceReflectanceFilter->GenerateAtmosphericRadiativeTerms();
      m_ReflectanceToSurfaceReflectanceFilter->GenerateParameters();
      m_ReflectanceToSurfaceReflectanceFilter->SetUseGenerateParameters(false);

      //rescale the surface reflectance in milli-reflectance
      m_ReflectanceToSurfaceReflectanceFilter->UpdateOutputInformation();
      m_ScaleFilter->SetInput(m_ReflectanceToSurfaceReflectanceFilter->GetOutput());
      }
      break;
      }

    // Output Image
    const double scale = IsParameterEnabled("milli") ? 1000.0 : 1.0;
    m_ScaleFilter->SetCoef(scale);

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

  ImageToLuminanceImageFilterType ::Pointer               m_ImageToLuminanceFilter;
  LuminanceToReflectanceImageFilterType::Pointer          m_LuminanceToReflectanceFilter;
  ReflectanceToSurfaceReflectanceImageFilterType::Pointer m_ReflectanceToSurfaceReflectanceFilter;
  ScaleFilterType::Pointer                                m_ScaleFilter;
  AtmosphericCorrectionParametersType::Pointer            m_AtmosphericParam;
};

}// namespace Wrapper
} // namespace otb

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


<commit_before>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <stdio.h>

#include <v8.h>

#include <node.h>
#include <node_version.h>
#include <node_buffer.h>

#include <openssl/bn.h>
#include <openssl/buffer.h>

#include "common.h"

using namespace std;
using namespace v8;
using namespace node;

static const char* BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

// input: Buffer, output: string
static Handle<Value>
base58_encode (const Arguments& args)
{
  HandleScope scope;

  if (args.Length() != 1) {
    return VException("One argument expected: a Buffer");
  }
  if (!Buffer::HasInstance(args[0])) {
    return VException("One argument expected: a Buffer");
  }
  v8::Handle<v8::Object> buf = args[0]->ToObject();

  unsigned char *buf_data = (unsigned char *) Buffer::Data(buf);
  int buf_length = Buffer::Length(buf);

  BN_CTX *ctx = BN_CTX_new();

  BIGNUM *bn = BN_bin2bn(buf_data, buf_length, NULL);

  BIGNUM *bn58 = BN_new();
  BN_set_word(bn58, 58);

  BIGNUM *bn0 = BN_new();
  BN_set_word(bn0, 0);

  BIGNUM *dv = BN_new();
  BIGNUM *rem = BN_new();

  // TODO: compute safe length
  char *str = new char[100];
  unsigned int c;
  int i, j, j2;

  i = 0;
  while (BN_cmp(bn, bn0) > 0) {
    if (!BN_div(dv, rem, bn, bn58, ctx)) {
      delete[] str;
      return VException("BN_div failed");
    }
    if (bn != dv) {
      BN_free(bn);
      bn = dv;
    }
    c = BN_get_word(rem);
    str[i] = BASE58_ALPHABET[c];
    i++;
  }

  // Leading zeros
  for (j = 0; j < buf_length; j++) {
    if (buf_data[j] != 0) {
      break;
    }
    str[i] = BASE58_ALPHABET[0];
    i++;
  }

  // Terminator
  str[i] = 0;

  // Reverse string
  int numSwaps = (i / 2);
  char tmp;
  for (j = 0; j < numSwaps; j++) {
    j2 = i - 1 - j;
    tmp = str[j];
    str[j] = str[j2];
    str[j2] = tmp;
  }

  BN_free(bn);
  BN_free(bn58);
  BN_free(bn0);
  BN_free(rem);
  BN_CTX_free(ctx);

  Local<String> ret = String::New(str);
  delete [] str;
  return scope.Close(ret);
}

// input: string, output: Buffer
static Handle<Value>
base58_decode (const Arguments& args)
{
  HandleScope scope;

  if (args.Length() != 1) {
    return VException("One argument expected: a String");
  }
  if (!args[0]->IsString()) {
    return VException("One argument expected: a String");
  }

  BN_CTX *ctx = BN_CTX_new();

  BIGNUM *bn58 = BN_new();
  BN_set_word(bn58, 58);

  BIGNUM *bn = BN_new();
  BN_set_word(bn, 0);

  BIGNUM *bnChar = BN_new();

  String::Utf8Value str(args[0]->ToString());
  char *psz = *str;

  while (isspace(*psz))
    psz++;

  // Convert big endian string to bignum
  for (const char* p = psz; *p; p++) {
    const char* p1 = strchr(BASE58_ALPHABET, *p);
    if (p1 == NULL) {
      while (isspace(*p))
        p++;
      if (*p != '\0')
        return VException("Error");
      break;
    }
    BN_set_word(bnChar, p1 - BASE58_ALPHABET);
    if (!BN_mul(bn, bn, bn58, ctx))
      return VException("BN_mul failed");
    if (!BN_add(bn, bn, bnChar))
      return VException("BN_add failed");
  }

  // Get bignum as little endian data
  unsigned int tmpLen = BN_num_bytes(bn);
  unsigned char *tmp = (unsigned char *)malloc(tmpLen);
  BN_bn2bin(bn, tmp);

  // Trim off sign byte if present
  if (tmpLen >= 2 && tmp[tmpLen-1] == 0 && tmp[tmpLen-2] >= 0x80)
    tmpLen--;

  // Restore leading zeros
  int nLeadingZeros = 0;
  for (const char* p = psz; *p == BASE58_ALPHABET[0]; p++)
    nLeadingZeros++;

  // Allocate buffer and zero it
  Buffer *buf = Buffer::New(nLeadingZeros + tmpLen);
  char* data = Buffer::Data(buf);
  memset(data, 0, nLeadingZeros + tmpLen);
  memcpy(data+nLeadingZeros, tmp, tmpLen);

  BN_free(bn58);
  BN_free(bn);
  BN_free(bnChar);
  BN_CTX_free(ctx);
  free(tmp);

  return scope.Close(buf->handle_);
}

extern "C" void
init (Handle<Object> target)
{
  HandleScope scope;
  target->Set(String::New("base58_encode"), FunctionTemplate::New(base58_encode)->GetFunction());
  target->Set(String::New("base58_decode"), FunctionTemplate::New(base58_decode)->GetFunction());
}

NODE_MODULE(base58, init)
<commit_msg>base58.cc: Fix many memory leaks<commit_after>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <stdio.h>

#include <v8.h>

#include <node.h>
#include <node_version.h>
#include <node_buffer.h>

#include <openssl/bn.h>
#include <openssl/buffer.h>

#include "common.h"

using namespace std;
using namespace v8;
using namespace node;

static const char* BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

// input: Buffer, output: string
static Handle<Value>
base58_encode (const Arguments& args)
{
  HandleScope scope;

  if (args.Length() != 1) {
    return VException("One argument expected: a Buffer");
  }
  if (!Buffer::HasInstance(args[0])) {
    return VException("One argument expected: a Buffer");
  }
  v8::Handle<v8::Object> buf = args[0]->ToObject();

  unsigned char *buf_data = (unsigned char *) Buffer::Data(buf);
  int buf_length = Buffer::Length(buf);

  BN_CTX *ctx = BN_CTX_new();

  BIGNUM *bn = BN_bin2bn(buf_data, buf_length, NULL);

  BIGNUM *bn58 = BN_new();
  BN_set_word(bn58, 58);

  BIGNUM *bn0 = BN_new();
  BN_set_word(bn0, 0);

  BIGNUM *dv = BN_new();
  BIGNUM *rem = BN_new();

  // FIXME! compute safe length.
  char *str = new char[100];
  unsigned int c;
  int i, j, j2;

  i = 0;
  while (BN_cmp(bn, bn0) > 0) {
    if (!BN_div(dv, rem, bn, bn58, ctx)) {
      BN_free(bn);
      BN_free(bn58);
      BN_free(bn0);
      if (bn != dv)
        BN_free(dv);
      BN_free(rem);
      BN_CTX_free(ctx);

      delete [] str;

      return VException("BN_div failed");
    }

    if (bn != dv) {
      BN_free(bn);
      bn = dv;
    }
    c = BN_get_word(rem);
    str[i] = BASE58_ALPHABET[c];
    i++;
  }

  // Leading zeros
  for (j = 0; j < buf_length; j++) {
    if (buf_data[j] != 0) {
      break;
    }
    str[i] = BASE58_ALPHABET[0];
    i++;
  }

  // Terminator
  str[i] = 0;

  // Reverse string
  int numSwaps = (i / 2);
  char tmp;
  for (j = 0; j < numSwaps; j++) {
    j2 = i - 1 - j;
    tmp = str[j];
    str[j] = str[j2];
    str[j2] = tmp;
  }

  BN_free(bn);
  BN_free(bn58);
  BN_free(bn0);
  BN_free(rem);
  BN_CTX_free(ctx);

  Local<String> ret = String::New(str);
  delete [] str;
  return scope.Close(ret);
}

// input: string, output: Buffer
static Handle<Value>
base58_decode (const Arguments& args)
{
  HandleScope scope;
  const char *errmsg = NULL;
  int nLeadingZeros = 0;
  Buffer *buf = NULL;
  char* data = NULL;
  unsigned int tmpLen = 0;
  unsigned char *tmp = NULL;

  if (args.Length() != 1) {
    return VException("One argument expected: a String");
  }
  if (!args[0]->IsString()) {
    return VException("One argument expected: a String");
  }

  BN_CTX *ctx = BN_CTX_new();

  BIGNUM *bn58 = BN_new();
  BN_set_word(bn58, 58);

  BIGNUM *bn = BN_new();
  BN_set_word(bn, 0);

  BIGNUM *bnChar = BN_new();

  String::Utf8Value str(args[0]->ToString());
  char *psz = *str;

  while (isspace(*psz))
    psz++;

  // Convert big endian string to bignum
  for (const char* p = psz; *p; p++) {
    const char* p1 = strchr(BASE58_ALPHABET, *p);
    if (p1 == NULL) {
      while (isspace(*p))
        p++;
      if (*p != '\0') {
	errmsg = "Error";
	goto err_out;
      }
      break;
    }
    BN_set_word(bnChar, p1 - BASE58_ALPHABET);
    if (!BN_mul(bn, bn, bn58, ctx)) {
      errmsg = "BN_mul failed";
      goto err_out;
    }
    if (!BN_add(bn, bn, bnChar)) {
      errmsg = "BN_add failed";
      goto err_out;
    }
  }

  // Get bignum as little endian data
  tmpLen = BN_num_bytes(bn);
  tmp = (unsigned char *)malloc(tmpLen);
  BN_bn2bin(bn, tmp);

  // Trim off sign byte if present
  if (tmpLen >= 2 && tmp[tmpLen-1] == 0 && tmp[tmpLen-2] >= 0x80)
    tmpLen--;

  // Restore leading zeros
  for (const char* p = psz; *p == BASE58_ALPHABET[0]; p++)
    nLeadingZeros++;

  // Allocate buffer and zero it
  buf = Buffer::New(nLeadingZeros + tmpLen);
  data = Buffer::Data(buf);
  memset(data, 0, nLeadingZeros + tmpLen);
  memcpy(data+nLeadingZeros, tmp, tmpLen);

  BN_free(bn58);
  BN_free(bn);
  BN_free(bnChar);
  BN_CTX_free(ctx);
  free(tmp);

  return scope.Close(buf->handle_);

err_out:
  BN_free(bn58);
  BN_free(bn);
  BN_free(bnChar);
  BN_CTX_free(ctx);
  return VException(errmsg);
}

extern "C" void
init (Handle<Object> target)
{
  HandleScope scope;
  target->Set(String::New("base58_encode"), FunctionTemplate::New(base58_encode)->GetFunction());
  target->Set(String::New("base58_decode"), FunctionTemplate::New(base58_decode)->GetFunction());
}

NODE_MODULE(base58, init)
<|endoftext|>


<commit_before>/****************************************************************************
*
* NAME: smbPitchShift.cpp
* VERSION: 1.2
* HOME URL: http://blogs.zynaptiq.com/bernsee
* KNOWN BUGS: none
*
* SYNOPSIS: Routine for doing pitch shifting while maintaining
* duration using the Short Time Fourier Transform.
*
* DESCRIPTION: The routine takes a pitchShift factor value which is between 0.5
* (one octave down) and 2. (one octave up). A value of exactly 1 does not change
* the pitch. numSampsToProcess tells the routine how many samples in indata[0...
* numSampsToProcess-1] should be pitch shifted and moved to outdata[0 ...
* numSampsToProcess-1]. The two buffers can be identical (ie. it can process the
* data in-place). fftFrameSize defines the FFT frame size used for the
* processing. Typical values are 1024, 2048 and 4096. It may be any value <=
* MAX_FRAME_LENGTH but it MUST be a power of 2. oversamp is the STFT
* oversampling factor which also determines the overlap between adjacent STFT
* frames. It should at least be 4 for moderate scaling ratios. A value of 32 is
* recommended for best quality. sampleRate takes the sample rate for the signal
* in unit Hz, ie. 44100 for 44.1 kHz audio. The data passed to the routine in
* indata[] should be in the range [-1.0, 1.0), which is also the output range
* for the data, make sure you scale the data accordingly (for 16bit signed integers
* you would have to divide (and multiply) by 32768).
*
* COPYRIGHT 1999-2015 Stephan M. Bernsee <s.bernsee [AT] zynaptiq [DOT] com>
*
* 						The Wide Open License (WOL)
*
* Permission to use, copy, modify, distribute and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice and this license appear in all source copies.
* THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF
* ANY KIND. See http://www.dspguru.com/wol.htm for more information.
*
*****************************************************************************/

#ifndef SMBPITCHSHIFT_HPP
#define SMBPITCHSHIFT_HPP

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstring>

namespace smb
{
    static const float PI = 3.14159265358979323846F;
    static const unsigned long MAX_FRAME_LENGTH = 8192;

    static void fft(std::complex<float>* fftBuffer, unsigned long fftFrameSize, long sign)
    {
        for (unsigned long i = 1; i < fftFrameSize - 1; i++)
        {
            unsigned long j = 0;

            for (unsigned long bitm = 1; bitm < fftFrameSize; bitm <<= 1)
            {
                if (i & bitm) j++;
                j <<= 1;
            }
            j >>= 1;

            if (i < j)
                std::swap(fftBuffer[i], fftBuffer[j]);
        }

        unsigned long step = 2;
        for (unsigned long i = 1; i < fftFrameSize; i <<= 1, step <<= 1)
        {
            unsigned long step2 = step >> 1;
            float arg = PI / step2;

            std::complex<float> w{std::cos(arg), std::sin(arg) * sign};
            std::complex<float> u{1.0, 0.0};
            for (unsigned long j = 0; j < step2; j++)
            {
                for (unsigned long k = j; k < fftFrameSize; k += step)
                {
                    // don't use operator* because it is slow
                    // temp = fftBuffer[k + step2] * u
                    std::complex<float> temp;
                    temp.real(fftBuffer[k + step2].real() * u.real() - fftBuffer[k + step2].imag() * u.imag());
                    temp.imag(fftBuffer[k + step2].real() * u.imag() + fftBuffer[k + step2].imag() * u.real());

                    fftBuffer[k + step2] = fftBuffer[k] - temp;
                    fftBuffer[k] += temp;
                }

                // don't use operator*= because it is slow
                // u *= w;
                float tempReal = u.real();
                u.real(tempReal * w.real() - u.imag() * w.imag());
                u.imag(tempReal * w.imag() + u.imag() * w.real());

            }
        }
    }

    class PitchShift
    {
    public:
        PitchShift()
        {
            std::fill(std::begin(inFIFO), std::end(inFIFO), 0.0F);
            std::fill(std::begin(outFIFO), std::end(outFIFO), 0.0F);
            std::fill(std::begin(fftWorksp), std::end(fftWorksp), std::complex<float>{0.0F, 0.0F});
            std::fill(std::begin(lastPhase), std::end(lastPhase), 0.0F);
            std::fill(std::begin(sumPhase), std::end(sumPhase), 0.0F);
            std::fill(std::begin(outputAccum), std::end(outputAccum), 0.0F);
            std::fill(std::begin(anaFreq), std::end(anaFreq), 0.0F);
            std::fill(std::begin(anaMagn), std::end(anaMagn), 0.0F);
        }

        /*
            Routine process(). See top of file for explanation
            Purpose: doing pitch shifting while maintaining duration using the Short
            Time Fourier Transform.
            Author: (c)1999-2015 Stephan M. Bernsee <s.bernsee [AT] zynaptiq [DOT] com>
        */
        void process(float pitchShift, unsigned long numSampsToProcess, unsigned long fftFrameSize,
                     unsigned long oversamp, float sampleRate, float* indata, float* outdata)
        {
            // set up some handy variables
            unsigned long fftFrameSize2 = fftFrameSize / 2;
            unsigned long stepSize = fftFrameSize / oversamp;
            float freqPerBin = sampleRate / static_cast<float>(fftFrameSize);
            float expct = 2.0F * PI * static_cast<float>(stepSize) / static_cast<float>(fftFrameSize);
            unsigned long inFifoLatency = fftFrameSize - stepSize;
            if (rover == 0) rover = inFifoLatency;

            // main processing loop
            for (unsigned long i = 0; i < numSampsToProcess; i++)
            {
                // As long as we have not yet collected enough data just read in
                inFIFO[rover] = indata[i];
                outdata[i] = outFIFO[rover - inFifoLatency];
                rover++;

                // now we have enough data for processing
                if (rover >= fftFrameSize)
                {
                    rover = inFifoLatency;

                    // do windowing and re,im interleave
                    for (unsigned long k = 0; k < fftFrameSize; k++)
                    {
                        float window = -0.5F * std::cos(2.0F * PI * static_cast<float>(k) / static_cast<float>(fftFrameSize)) + 0.5F;
                        fftWorksp[k].real(inFIFO[k] * window);
                        fftWorksp[k].imag(0.0F);
                    }

                    // ***************** ANALYSIS *******************
                    // do transform
                    fft(fftWorksp, fftFrameSize, -1);

                    // this is the analysis step
                    for (unsigned long k = 0; k <= fftFrameSize2; k++)
                    {
                        // de-interlace FFT buffer
                        float real = fftWorksp[k].real();
                        float imag = fftWorksp[k].imag();

                        // compute magnitude and phase
                        float magn = 2.0F * sqrtf(real * real + imag * imag);

                        float phase;
                        float signx = (imag > 0.0F) ? 1.0F : -1.0F;
                        if (imag == 0.0F) phase = 0.0F;
                        else if (real == 0.0F) phase = signx * PI / 2.0F;
                        else phase = std::atan2(imag, real);

                        // compute phase difference
                        float tmp = phase - lastPhase[k];
                        lastPhase[k] = phase;

                        // subtract expected phase difference
                        tmp -= static_cast<float>(k) * expct;

                        // map delta phase into +/- Pi interval
                        long qpd = static_cast<long>(tmp / PI);
                        if (qpd >= 0) qpd += qpd & 1;
                        else qpd -= qpd & 1;
                        tmp -= PI * static_cast<float>(qpd);

                        // get deviation from bin frequency from the +/- Pi interval
                        tmp = oversamp * tmp / (2.0F * PI);

                        // compute the k-th partials' true frequency
                        tmp = static_cast<float>(k) * freqPerBin + tmp * freqPerBin;

                        // store magnitude and true frequency in analysis arrays
                        anaMagn[k] = magn;
                        anaFreq[k] = tmp;
                    }

                    // ***************** PROCESSING *******************
                    // this does the actual pitch shifting
                    std::fill(std::begin(synMagn), std::begin(synMagn) + fftFrameSize, 0.0F);
                    std::fill(std::begin(synFreq), std::begin(synFreq) + fftFrameSize, 0.0F);
                    for (unsigned long k = 0; k <= fftFrameSize2; k++)
                    {
                        unsigned long index = static_cast<unsigned long>(k * pitchShift);
                        if (index <= fftFrameSize2)
                        {
                            synMagn[index] += anaMagn[k];
                            synFreq[index] = anaFreq[k] * pitchShift;
                        }
                    }

                    // ***************** SYNTHESIS *******************
                    // this is the synthesis step
                    for (unsigned long k = 0; k <= fftFrameSize2; k++)
                    {
                        // get magnitude and true frequency from synthesis arrays
                        float magn = synMagn[k];
                        float tmp = synFreq[k];

                        // subtract bin mid frequency
                        tmp -= static_cast<float>(k) * freqPerBin;

                        // get bin deviation from freq deviation
                        tmp /= freqPerBin;

                        // take oversampling factor into account
                        tmp = 2.0F * PI * tmp / oversamp;

                        // add the overlap phase advance back in
                        tmp += static_cast<float>(k) * expct;

                        // accumulate delta phase to get bin phase
                        sumPhase[k] += tmp;
                        float phase = sumPhase[k];

                        // get real and imag part and re-interleave
                        fftWorksp[k].real(magn * std::cos(phase));
                        fftWorksp[k].imag(magn * std::sin(phase));
                    }

                    // zero negative frequencies
                    for (unsigned long k = fftFrameSize + 1; k < fftFrameSize; k++) fftWorksp[k] = {0.0F, 0.0F};

                    // do inverse transform
                    fft(fftWorksp, fftFrameSize, 1);

                    // do windowing and add to output accumulator
                    for (unsigned long k = 0; k < fftFrameSize; k++)
                    {
                        float window = -0.5F * cos(2.0F * PI * static_cast<float>(k) / static_cast<float>(fftFrameSize)) + 0.5F;
                        outputAccum[k] += 2.0F * window * fftWorksp[k].real() / (fftFrameSize2 * oversamp);
                    }
                    unsigned long k;
                    for (k = 0 ; k < stepSize; k++) outFIFO[k] = outputAccum[k];
                    // shift accumulator
                    unsigned long j;
                    for (j = 0; k < fftFrameSize; k++, j++) outputAccum[j] = outputAccum[k];
                    for (; j < fftFrameSize; j++) outputAccum[j] = 0.0;

                    // move input FIFO
                    for (k = 0; k < inFifoLatency; k++) inFIFO[k] = inFIFO[k + stepSize];
                }
            }
        }

    private:
        float inFIFO[MAX_FRAME_LENGTH];
        float outFIFO[MAX_FRAME_LENGTH];
        std::complex<float> fftWorksp[MAX_FRAME_LENGTH];
        float lastPhase[MAX_FRAME_LENGTH / 2 + 1];
        float sumPhase[MAX_FRAME_LENGTH / 2 + 1];
        float outputAccum[2 * MAX_FRAME_LENGTH];
        float anaFreq[MAX_FRAME_LENGTH];
        float anaMagn[MAX_FRAME_LENGTH];
        float synFreq[MAX_FRAME_LENGTH];
        float synMagn[MAX_FRAME_LENGTH];
        unsigned long rover = 0;
    };
}

#endif
<commit_msg>Use own implementation of complex<commit_after>/****************************************************************************
*
* NAME: smbPitchShift.cpp
* VERSION: 1.2
* HOME URL: http://blogs.zynaptiq.com/bernsee
* KNOWN BUGS: none
*
* SYNOPSIS: Routine for doing pitch shifting while maintaining
* duration using the Short Time Fourier Transform.
*
* DESCRIPTION: The routine takes a pitchShift factor value which is between 0.5
* (one octave down) and 2. (one octave up). A value of exactly 1 does not change
* the pitch. numSampsToProcess tells the routine how many samples in indata[0...
* numSampsToProcess-1] should be pitch shifted and moved to outdata[0 ...
* numSampsToProcess-1]. The two buffers can be identical (ie. it can process the
* data in-place). fftFrameSize defines the FFT frame size used for the
* processing. Typical values are 1024, 2048 and 4096. It may be any value <=
* MAX_FRAME_LENGTH but it MUST be a power of 2. oversamp is the STFT
* oversampling factor which also determines the overlap between adjacent STFT
* frames. It should at least be 4 for moderate scaling ratios. A value of 32 is
* recommended for best quality. sampleRate takes the sample rate for the signal
* in unit Hz, ie. 44100 for 44.1 kHz audio. The data passed to the routine in
* indata[] should be in the range [-1.0, 1.0), which is also the output range
* for the data, make sure you scale the data accordingly (for 16bit signed integers
* you would have to divide (and multiply) by 32768).
*
* COPYRIGHT 1999-2015 Stephan M. Bernsee <s.bernsee [AT] zynaptiq [DOT] com>
*
* 						The Wide Open License (WOL)
*
* Permission to use, copy, modify, distribute and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice and this license appear in all source copies.
* THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF
* ANY KIND. See http://www.dspguru.com/wol.htm for more information.
*
*****************************************************************************/

#ifndef SMBPITCHSHIFT_HPP
#define SMBPITCHSHIFT_HPP

#include <algorithm>
#include <cmath>
#include <cstring>

namespace smb
{
    static const float PI = 3.14159265358979323846F;
    static const unsigned long MAX_FRAME_LENGTH = 8192;

    // Use own implementation because std::complex has a poor performance
    template<class T>
    struct Complex
    {
        inline Complex<T> operator+(const Complex& other)
        {
            return Complex{real + other.real, imag + other.imag};
        }

        inline Complex<T>& operator+=(const Complex& other)
        {
            real += other.real;
            imag += other.imag;
            return *this;
        }

        inline Complex<T> operator-(const Complex& other)
        {
            return Complex{real - other.real, imag - other.imag};
        }

        inline Complex<T>& operator-=(const Complex& other)
        {
            real -= other.real;
            imag -= other.imag;
            return *this;
        }

        inline Complex<T> operator*(const Complex& other)
        {
            return Complex{real * other.real - imag * other.imag, real * other.imag + imag * other.real};
        }

        inline Complex<T>& operator*=(const Complex& other)
        {
            float tempReal = real;
            real = tempReal * other.real - imag * other.imag;
            imag = tempReal * other.imag + imag * other.real;
            return *this;
        }

        T real;
        T imag;
    };

    static void fft(Complex<float>* fftBuffer, unsigned long fftFrameSize, long sign)
    {
        for (unsigned long i = 1; i < fftFrameSize - 1; i++)
        {
            unsigned long j = 0;

            for (unsigned long bitm = 1; bitm < fftFrameSize; bitm <<= 1)
            {
                if (i & bitm) j++;
                j <<= 1;
            }
            j >>= 1;

            if (i < j)
                std::swap(fftBuffer[i], fftBuffer[j]);
        }

        unsigned long step = 2;
        for (unsigned long i = 1; i < fftFrameSize; i <<= 1, step <<= 1)
        {
            unsigned long step2 = step >> 1;
            float arg = PI / step2;

            Complex<float> w{std::cos(arg), std::sin(arg) * sign};
            Complex<float> u{1.0, 0.0};
            for (unsigned long j = 0; j < step2; j++)
            {
                for (unsigned long k = j; k < fftFrameSize; k += step)
                {
                    Complex<float> temp = fftBuffer[k + step2] * u;
                    fftBuffer[k + step2] = fftBuffer[k] - temp;
                    fftBuffer[k] += temp;
                }

                u *= w;
            }
        }
    }

    class PitchShift
    {
    public:
        PitchShift()
        {
            std::fill(std::begin(inFIFO), std::end(inFIFO), 0.0F);
            std::fill(std::begin(outFIFO), std::end(outFIFO), 0.0F);
            std::fill(std::begin(fftWorksp), std::end(fftWorksp), Complex<float>{0.0F, 0.0F});
            std::fill(std::begin(lastPhase), std::end(lastPhase), 0.0F);
            std::fill(std::begin(sumPhase), std::end(sumPhase), 0.0F);
            std::fill(std::begin(outputAccum), std::end(outputAccum), 0.0F);
            std::fill(std::begin(anaFreq), std::end(anaFreq), 0.0F);
            std::fill(std::begin(anaMagn), std::end(anaMagn), 0.0F);
        }

        /*
            Routine process(). See top of file for explanation
            Purpose: doing pitch shifting while maintaining duration using the Short
            Time Fourier Transform.
            Author: (c)1999-2015 Stephan M. Bernsee <s.bernsee [AT] zynaptiq [DOT] com>
        */
        void process(float pitchShift, unsigned long numSampsToProcess, unsigned long fftFrameSize,
                     unsigned long oversamp, float sampleRate, float* indata, float* outdata)
        {
            // set up some handy variables
            unsigned long fftFrameSize2 = fftFrameSize / 2;
            unsigned long stepSize = fftFrameSize / oversamp;
            float freqPerBin = sampleRate / static_cast<float>(fftFrameSize);
            float expct = 2.0F * PI * static_cast<float>(stepSize) / static_cast<float>(fftFrameSize);
            unsigned long inFifoLatency = fftFrameSize - stepSize;
            if (rover == 0) rover = inFifoLatency;

            // main processing loop
            for (unsigned long i = 0; i < numSampsToProcess; i++)
            {
                // As long as we have not yet collected enough data just read in
                inFIFO[rover] = indata[i];
                outdata[i] = outFIFO[rover - inFifoLatency];
                rover++;

                // now we have enough data for processing
                if (rover >= fftFrameSize)
                {
                    rover = inFifoLatency;

                    // do windowing and re,im interleave
                    for (unsigned long k = 0; k < fftFrameSize; k++)
                    {
                        float window = -0.5F * std::cos(2.0F * PI * static_cast<float>(k) / static_cast<float>(fftFrameSize)) + 0.5F;
                        fftWorksp[k].real = inFIFO[k] * window;
                        fftWorksp[k].imag = 0.0F;
                    }

                    // ***************** ANALYSIS *******************
                    // do transform
                    fft(fftWorksp, fftFrameSize, -1);

                    // this is the analysis step
                    for (unsigned long k = 0; k <= fftFrameSize2; k++)
                    {
                        // de-interlace FFT buffer
                        float real = fftWorksp[k].real;
                        float imag = fftWorksp[k].imag;

                        // compute magnitude and phase
                        float magn = 2.0F * sqrtf(real * real + imag * imag);

                        float phase;
                        float signx = (imag > 0.0F) ? 1.0F : -1.0F;
                        if (imag == 0.0F) phase = 0.0F;
                        else if (real == 0.0F) phase = signx * PI / 2.0F;
                        else phase = std::atan2(imag, real);

                        // compute phase difference
                        float tmp = phase - lastPhase[k];
                        lastPhase[k] = phase;

                        // subtract expected phase difference
                        tmp -= static_cast<float>(k) * expct;

                        // map delta phase into +/- Pi interval
                        long qpd = static_cast<long>(tmp / PI);
                        if (qpd >= 0) qpd += qpd & 1;
                        else qpd -= qpd & 1;
                        tmp -= PI * static_cast<float>(qpd);

                        // get deviation from bin frequency from the +/- Pi interval
                        tmp = oversamp * tmp / (2.0F * PI);

                        // compute the k-th partials' true frequency
                        tmp = static_cast<float>(k) * freqPerBin + tmp * freqPerBin;

                        // store magnitude and true frequency in analysis arrays
                        anaMagn[k] = magn;
                        anaFreq[k] = tmp;
                    }

                    // ***************** PROCESSING *******************
                    // this does the actual pitch shifting
                    std::fill(std::begin(synMagn), std::begin(synMagn) + fftFrameSize, 0.0F);
                    std::fill(std::begin(synFreq), std::begin(synFreq) + fftFrameSize, 0.0F);
                    for (unsigned long k = 0; k <= fftFrameSize2; k++)
                    {
                        unsigned long index = static_cast<unsigned long>(k * pitchShift);
                        if (index <= fftFrameSize2)
                        {
                            synMagn[index] += anaMagn[k];
                            synFreq[index] = anaFreq[k] * pitchShift;
                        }
                    }

                    // ***************** SYNTHESIS *******************
                    // this is the synthesis step
                    for (unsigned long k = 0; k <= fftFrameSize2; k++)
                    {
                        // get magnitude and true frequency from synthesis arrays
                        float magn = synMagn[k];
                        float tmp = synFreq[k];

                        // subtract bin mid frequency
                        tmp -= static_cast<float>(k) * freqPerBin;

                        // get bin deviation from freq deviation
                        tmp /= freqPerBin;

                        // take oversampling factor into account
                        tmp = 2.0F * PI * tmp / oversamp;

                        // add the overlap phase advance back in
                        tmp += static_cast<float>(k) * expct;

                        // accumulate delta phase to get bin phase
                        sumPhase[k] += tmp;
                        float phase = sumPhase[k];

                        // get real and imag part and re-interleave
                        fftWorksp[k].real = magn * std::cos(phase);
                        fftWorksp[k].imag = magn * std::sin(phase);
                    }

                    // zero negative frequencies
                    for (unsigned long k = fftFrameSize + 1; k < fftFrameSize; k++) fftWorksp[k] = {0.0F, 0.0F};

                    // do inverse transform
                    fft(fftWorksp, fftFrameSize, 1);

                    // do windowing and add to output accumulator
                    for (unsigned long k = 0; k < fftFrameSize; k++)
                    {
                        float window = -0.5F * cos(2.0F * PI * static_cast<float>(k) / static_cast<float>(fftFrameSize)) + 0.5F;
                        outputAccum[k] += 2.0F * window * fftWorksp[k].real / (fftFrameSize2 * oversamp);
                    }
                    unsigned long k;
                    for (k = 0 ; k < stepSize; k++) outFIFO[k] = outputAccum[k];
                    // shift accumulator
                    unsigned long j;
                    for (j = 0; k < fftFrameSize; k++, j++) outputAccum[j] = outputAccum[k];
                    for (; j < fftFrameSize; j++) outputAccum[j] = 0.0;

                    // move input FIFO
                    for (k = 0; k < inFifoLatency; k++) inFIFO[k] = inFIFO[k + stepSize];
                }
            }
        }

    private:
        float inFIFO[MAX_FRAME_LENGTH];
        float outFIFO[MAX_FRAME_LENGTH];
        Complex<float> fftWorksp[MAX_FRAME_LENGTH];
        float lastPhase[MAX_FRAME_LENGTH / 2 + 1];
        float sumPhase[MAX_FRAME_LENGTH / 2 + 1];
        float outputAccum[2 * MAX_FRAME_LENGTH];
        float anaFreq[MAX_FRAME_LENGTH];
        float anaMagn[MAX_FRAME_LENGTH];
        float synFreq[MAX_FRAME_LENGTH];
        float synMagn[MAX_FRAME_LENGTH];
        unsigned long rover = 0;
    };
}

#endif
<|endoftext|>


<commit_before>#include "document.h"

using namespace std;

namespace wano {
	Document::Document(shared_ptr<EventQueue> eq) :
		buffer(),
		eq{ eq }
	{
		curs.x = 0;
		curs.y = 0;
		buffer.push_back(make_shared<vector<int>>(0));
	}

	coord Document::insCh(int ch) {
		auto by = buffer[curs.y];
		by->insert(by->begin() + curs.x, ch);
		return this->cursRight();
	}

	coord Document::delCh() {
		auto by = buffer[curs.y];
		if (curs.x < by->size()) {
			by->erase(by->begin() + curs.x);
		}
		return curs;
	}

	coord Document::newLine() {
		// TODO:: Split current line if needed
		buffer.insert(buffer.begin() + curs.y + 1, make_shared<vector<int>>(0));
		return this->cursMove(0, curs.y + 1);
	}

	coord Document::cursMove(int x, int y) {
		bool changedY = false;
		// Don't bother doing operations on unchanged coordinates
		if (y != curs.y) {
			changedY = true;
			if (y < 0) {
				curs.y = 0;
			}
			else if (buffer.size() > y) {
				curs.y = y;
			}
			else {
				curs.y = buffer.size() - 1;
			}
		}
		// If y changed, x may have to move
		if (x != curs.x || changedY) {
			auto by = buffer[curs.y];
			if (x < 0) {
				curs.x = 0;
			}
			else if (by->size() >= x) {
				curs.x = x;
			}
			else {
				curs.x = by->size();
			}
		}
		this->eq->fire<coord>(DOC_MOVE, curs);
		return curs;
	}

	coord Document::cursRight(int num) {
		return this->cursMove(curs.x + num, curs.y);
	}

	coord Document::cursRight() {
		return this->cursRight(1);
	}

	coord Document::cursLeft(int num) {
		return this->cursMove(curs.x - num, curs.y);
	}

	coord Document::cursLeft() {
		return this->cursLeft(1);
	}

	coord Document::cursDown(int num) {
		return this->cursMove(curs.x, curs.y + num);
	}

	coord Document::cursDown() {
		return this->cursDown(1);
	}

	coord Document::cursUp(int num) {
		return this->cursMove(curs.x, curs.y - num);
	}

	coord Document::cursUp() {
		return this->cursUp(1);
	}

	coord Document::cursEnd() {
		auto by = buffer[curs.y];
		return this->cursMove(by->size(), curs.y);
	}

	coord Document::cursHome() {
		return this->cursMove(0, curs.y);
	}

	vector<int> Document::readLine(int line) {
		// Copying may not be the way to go, but it is a pretty
		// small vector
		return vector<int>(*buffer[line]);
	}
}<commit_msg>Fixed typo in variable type<commit_after>#include "document.h"

using namespace std;

namespace wano {
	Document::Document(shared_ptr<EventQueue> eq) :
		buffer(),
		eq{ eq }
	{
		curs.x = 0;
		curs.y = 0;
		buffer.push_back(make_shared<vector<int>>(0));
	}

	coord Document::insCh(int ch) {
		auto by = buffer[curs.y];
		by->insert(by->begin() + curs.x, ch);
		return this->cursRight();
	}

	coord Document::delCh() {
		auto by = buffer[curs.y];
		if (curs.x < by->size()) {
			by->erase(by->begin() + curs.x);
		}
		return curs;
	}

	coord Document::newLine() {
		// TODO:: Split current line if needed
		buffer.insert(buffer.begin() + curs.y + 1, make_shared<vector<int>>(0));
		return this->cursMove(0, curs.y + 1);
	}

	coord Document::cursMove(int x, int y) {
		auto changedY = false;
		// Don't bother doing operations on unchanged coordinates
		if (y != curs.y) {
			changedY = true;
			if (y < 0) {
				curs.y = 0;
			}
			else if (buffer.size() > y) {
				curs.y = y;
			}
			else {
				curs.y = buffer.size() - 1;
			}
		}
		// If y changed, x may have to move
		if (x != curs.x || changedY) {
			auto by = buffer[curs.y];
			if (x < 0) {
				curs.x = 0;
			}
			else if (by->size() >= x) {
				curs.x = x;
			}
			else {
				curs.x = by->size();
			}
		}
		this->eq->fire<coord>(DOC_MOVE, curs);
		return curs;
	}

	coord Document::cursRight(int num) {
		return this->cursMove(curs.x + num, curs.y);
	}

	coord Document::cursRight() {
		return this->cursRight(1);
	}

	coord Document::cursLeft(int num) {
		return this->cursMove(curs.x - num, curs.y);
	}

	coord Document::cursLeft() {
		return this->cursLeft(1);
	}

	coord Document::cursDown(int num) {
		return this->cursMove(curs.x, curs.y + num);
	}

	coord Document::cursDown() {
		return this->cursDown(1);
	}

	coord Document::cursUp(int num) {
		return this->cursMove(curs.x, curs.y - num);
	}

	coord Document::cursUp() {
		return this->cursUp(1);
	}

	coord Document::cursEnd() {
		auto by = buffer[curs.y];
		return this->cursMove(by->size(), curs.y);
	}

	coord Document::cursHome() {
		return this->cursMove(0, curs.y);
	}

	vector<int> Document::readLine(int line) {
		// Copying may not be the way to go, but it is a pretty
		// small vector
		return vector<int>(*buffer[line]);
	}
}
<|endoftext|>


<commit_before>// game.m.cpp
#include "engine/build.g.h"
#include "engine/input/input.h"
#include "engine/rendering/renderer.h"
#include "engine/scene/scene.h"
#include "engine/scene/test_input_controller.h"
#include "engine/util/input_utils.h"
#include "engine/util/game_utils.h"

int main( int argc, char *argv[] )
{
    using namespace std;
    using namespace StevensDev;
    using namespace StevensDev::sgdu;

    int i;

    // print out debug information
    cout << "CS 585 Intro to Game Development" << endl;
    cout << "Game" << endl;
    cout << "Version: " << GAME_VERSION << endl;

    cout << "Arguments: ";
    for ( i = 1; i < argc; ++i )
    {
        cout << argv[i] << " ";
    }
    cout << endl;

    // set up game
    sgdi::Input& input = sgdi::Input::inst();
    sgds::Scene& scene = sgds::Scene::inst();
    sgdr::Renderer renderer;

    assert( renderer.loadTexture( "block", "res/texture/block.png" ) );
    sgdr::RenderableSprite sprite( renderer.getTexture( "block" ) );

    renderer.addSprite( &sprite );

    scene.addTickable( &input );
    scene.setRenderer( &renderer );

    renderer.setupWindow( 800, 600 );

    while ( renderer.isActive() )
    {
        scene.tick();
    }

    cout << "Finished. Exiting..." << endl;

    return 0;
}<commit_msg>Remove invalid import<commit_after>// game.m.cpp
#include "engine/build.g.h"
#include "engine/input/input.h"
#include "engine/rendering/renderer.h"
#include "engine/scene/scene.h"
#include "engine/util/input_utils.h"
#include "engine/util/game_utils.h"

int main( int argc, char *argv[] )
{
    using namespace std;
    using namespace StevensDev;
    using namespace StevensDev::sgdu;

    int i;

    // print out debug information
    cout << "CS 585 Intro to Game Development" << endl;
    cout << "Game" << endl;
    cout << "Version: " << GAME_VERSION << endl;

    cout << "Arguments: ";
    for ( i = 1; i < argc; ++i )
    {
        cout << argv[i] << " ";
    }
    cout << endl;

    // set up game
    sgdi::Input& input = sgdi::Input::inst();
    sgds::Scene& scene = sgds::Scene::inst();
    sgdr::Renderer renderer;

    assert( renderer.loadTexture( "block", "res/texture/block.png" ) );
    sgdr::RenderableSprite sprite( renderer.getTexture( "block" ) );

    renderer.addSprite( &sprite );

    scene.addTickable( &input );
    scene.setRenderer( &renderer );

    renderer.setupWindow( 800, 600 );

    while ( renderer.isActive() )
    {
        scene.tick();
    }

    cout << "Finished. Exiting..." << endl;

    return 0;
}<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2011
  \file      calc_array.cpp
  \author
  \date      02.05.2011
  \brief        -
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "simulator/runtime/pch/stdpch.h"
// ----------------------------------------------------------------------- INCLUDES
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/runtime/calc/calc_array.h"
#include "simulator/runtime/rdo_array.h"
#include "simulator/runtime/rdo_res_type.h"
// --------------------------------------------------------------------------------

OPEN_RDO_RUNTIME_NAMESPACE

// --------------------------------------------------------------------------------
// -------------------- RDOCalcArraySize
// --------------------------------------------------------------------------------
RDOCalcArraySize::RDOCalcArraySize(CREF(LPRDOCalc) pCalc)
	: m_pCalc(pCalc)
{}

RDOValue RDOCalcArraySize::doCalc(CREF(LPRDORuntime) pRuntime)
{
	RDOValue value = m_pCalc->calcValue(pRuntime);
	CREF(LPRDOArrayValue) pArrayValue = value.getPointerSafety<RDOArrayType>();
	ASSERT(pArrayValue);
	return pArrayValue->size();
}

// --------------------------------------------------------------------------------
// -------------------- RDOCalcArrayItem
// --------------------------------------------------------------------------------
RDOCalcArrayItem::RDOCalcArrayItem(CREF(LPRDOCalc) pArray, CREF(LPRDOCalc) pArrayInd)
	: m_pArray   (pArray   )
	, m_pArrayInd(pArrayInd)
{
	ASSERT(m_pArray   );
	ASSERT(m_pArrayInd);

	setSrcInfo(m_pArrayInd->srcInfo());
}

RDOValue RDOCalcArrayItem::doCalc(CREF(LPRDORuntime) pRuntime)
{
	RDOValue value = m_pArray->calcValue(pRuntime);

	CREF(LPRDOArrayValue) pArrayValue = value.getPointerSafety<RDOArrayType>();
	ASSERT(pArrayValue);

	return pArrayValue->getItem(m_pArrayInd->calcValue(pRuntime));
}

// --------------------------------------------------------------------------------
// -------------------- RDOCalcArrayItemParam
// --------------------------------------------------------------------------------
RDOCalcArrayItemParam::RDOCalcArrayItemParam(CREF(LPRDOCalc) pArray, CREF(LPRDOCalc) pArrayInd, CREF(LPRDOCalc) pParamInd)
: m_pArray   (pArray   )
, m_pArrayInd(pArrayInd)
, m_pParamInd(pParamInd)
{
	ASSERT(m_pArray   );
	ASSERT(m_pArrayInd);
	ASSERT(m_pParamInd);

	setSrcInfo(m_pArrayInd->srcInfo());
}

RDOValue RDOCalcArrayItemParam::doCalc(CREF(LPRDORuntime) pRuntime)
{
	RDOValue value = m_pArray->calcValue(pRuntime);
	RDOValue param_ind = m_pParamInd->calcValue(pRuntime);

	CREF(LPRDOArrayValue) pArrayValue = value.getPointerSafety<RDOArrayType>();
	ASSERT(pArrayValue);

	RDOValue pArrayItem = pArrayValue->getItem(m_pArrayInd->calcValue(pRuntime));

	LPRDOResource pResource = pArrayItem.getPointerSafety<RDOResourceType>();
	ASSERT(pResource);

	return pResource->getParam(param_ind.getInt());
}

// --------------------------------------------------------------------------------
// -------------------- RDOCalcSetArrayItem
// --------------------------------------------------------------------------------
RDOCalcSetArrayItem::RDOCalcSetArrayItem(CREF(LPRDOCalc) pArray, CREF(LPRDOCalc) pArrayInd, CREF(LPRDOCalc) pSetItem)
	: m_pArray   (pArray   )
	, m_pArrayInd(pArrayInd)
	, m_pSetItem (pSetItem )
{
	ASSERT(m_pArray   );
	ASSERT(m_pArrayInd);
	ASSERT(m_pSetItem );

	setSrcInfo(m_pArrayInd->srcInfo());
}

RDOValue RDOCalcSetArrayItem::doCalc(CREF(LPRDORuntime) pRuntime)
{
	RDOValue value = m_pArray->calcValue(pRuntime);

	CREF(LPRDOArrayValue) pArrayValue = value.getPointerSafety<RDOArrayType>();
	ASSERT(pArrayValue);
	pArrayValue->setItem(m_pArrayInd->calcValue(pRuntime), m_pSetItem->calcValue(pRuntime));

	return value;
}

CLOSE_RDO_RUNTIME_NAMESPACE
<commit_msg> - форматирование<commit_after>/*!
  \copyright (c) RDO-Team, 2011
  \file      calc_array.cpp
  \author
  \date      02.05.2011
  \brief        -
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "simulator/runtime/pch/stdpch.h"
// ----------------------------------------------------------------------- INCLUDES
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/runtime/calc/calc_array.h"
#include "simulator/runtime/rdo_array.h"
#include "simulator/runtime/rdo_res_type.h"
// --------------------------------------------------------------------------------

OPEN_RDO_RUNTIME_NAMESPACE

// --------------------------------------------------------------------------------
// -------------------- RDOCalcArraySize
// --------------------------------------------------------------------------------
RDOCalcArraySize::RDOCalcArraySize(CREF(LPRDOCalc) pCalc)
	: m_pCalc(pCalc)
{}

RDOValue RDOCalcArraySize::doCalc(CREF(LPRDORuntime) pRuntime)
{
	RDOValue value = m_pCalc->calcValue(pRuntime);
	CREF(LPRDOArrayValue) pArrayValue = value.getPointerSafety<RDOArrayType>();
	ASSERT(pArrayValue);
	return pArrayValue->size();
}

// --------------------------------------------------------------------------------
// -------------------- RDOCalcArrayItem
// --------------------------------------------------------------------------------
RDOCalcArrayItem::RDOCalcArrayItem(CREF(LPRDOCalc) pArray, CREF(LPRDOCalc) pArrayInd)
	: m_pArray   (pArray   )
	, m_pArrayInd(pArrayInd)
{
	ASSERT(m_pArray   );
	ASSERT(m_pArrayInd);

	setSrcInfo(m_pArrayInd->srcInfo());
}

RDOValue RDOCalcArrayItem::doCalc(CREF(LPRDORuntime) pRuntime)
{
	RDOValue value = m_pArray->calcValue(pRuntime);

	CREF(LPRDOArrayValue) pArrayValue = value.getPointerSafety<RDOArrayType>();
	ASSERT(pArrayValue);

	return pArrayValue->getItem(m_pArrayInd->calcValue(pRuntime));
}

// --------------------------------------------------------------------------------
// -------------------- RDOCalcArrayItemParam
// --------------------------------------------------------------------------------
RDOCalcArrayItemParam::RDOCalcArrayItemParam(CREF(LPRDOCalc) pArray, CREF(LPRDOCalc) pArrayInd, CREF(LPRDOCalc) pParamInd)
	: m_pArray   (pArray   )
	, m_pArrayInd(pArrayInd)
	, m_pParamInd(pParamInd)
{
	ASSERT(m_pArray   );
	ASSERT(m_pArrayInd);
	ASSERT(m_pParamInd);

	setSrcInfo(m_pArrayInd->srcInfo());
}

RDOValue RDOCalcArrayItemParam::doCalc(CREF(LPRDORuntime) pRuntime)
{
	RDOValue value = m_pArray->calcValue(pRuntime);
	RDOValue param_ind = m_pParamInd->calcValue(pRuntime);

	CREF(LPRDOArrayValue) pArrayValue = value.getPointerSafety<RDOArrayType>();
	ASSERT(pArrayValue);

	RDOValue pArrayItem = pArrayValue->getItem(m_pArrayInd->calcValue(pRuntime));

	LPRDOResource pResource = pArrayItem.getPointerSafety<RDOResourceType>();
	ASSERT(pResource);

	return pResource->getParam(param_ind.getInt());
}

// --------------------------------------------------------------------------------
// -------------------- RDOCalcSetArrayItem
// --------------------------------------------------------------------------------
RDOCalcSetArrayItem::RDOCalcSetArrayItem(CREF(LPRDOCalc) pArray, CREF(LPRDOCalc) pArrayInd, CREF(LPRDOCalc) pSetItem)
	: m_pArray   (pArray   )
	, m_pArrayInd(pArrayInd)
	, m_pSetItem (pSetItem )
{
	ASSERT(m_pArray   );
	ASSERT(m_pArrayInd);
	ASSERT(m_pSetItem );

	setSrcInfo(m_pArrayInd->srcInfo());
}

RDOValue RDOCalcSetArrayItem::doCalc(CREF(LPRDORuntime) pRuntime)
{
	RDOValue value = m_pArray->calcValue(pRuntime);

	CREF(LPRDOArrayValue) pArrayValue = value.getPointerSafety<RDOArrayType>();
	ASSERT(pArrayValue);
	pArrayValue->setItem(m_pArrayInd->calcValue(pRuntime), m_pSetItem->calcValue(pRuntime));

	return value;
}

CLOSE_RDO_RUNTIME_NAMESPACE
<|endoftext|>


<commit_before>/**
 * \file
 * \brief PendSV_Handler() for ARMv7-M (Cortex-M3 / Cortex-M4)
 *
 * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-03-19
 */

#include "distortos/scheduler/getScheduler.hpp"
#include "distortos/scheduler/Scheduler.hpp"

#include "distortos/chip/CMSIS-proxy.h"

/*---------------------------------------------------------------------------------------------------------------------+
| global functions
+---------------------------------------------------------------------------------------------------------------------*/

/**
 * \brief Wrapper for void* distortos::scheduler::getScheduler().switchContext(void*)
 *
 * \param [in] stackPointer is the current value of current thread's stack pointer
 *
 * \return new thread's stack pointer
 */

extern "C" void* schedulerSwitchContextWrapper(void* const stackPointer)
{
	return distortos::scheduler::getScheduler().switchContext(stackPointer);
}

/**
 * \brief PendSV_Handler() for ARMv7-M (Cortex-M3 / Cortex-M4)
 *
 * Performs the context switch.
 */

extern "C" __attribute__ ((naked)) void PendSV_Handler()
{
	asm volatile
	(
			"	mrs		r0, PSP								\n"
#if __FPU_PRESENT == 1 && __FPU_USED == 1
			"	stmdb	r0!, {r4-r11, lr}					\n"	// save context of current thread
#else
			"	stmdb	r0!, {r4-r11}						\n"	// save context of current thread
			"	mov		r4, lr								\n"
#endif	// __FPU_PRESENT == 1 && __FPU_USED == 1
			"												\n"
			"	bl		schedulerSwitchContextWrapper		\n"	// switch context
			"												\n"
#if __FPU_PRESENT == 1 && __FPU_USED == 1
			"	ldmia	r0!, {r4-r11, lr}					\n"	// load context of new thread
#else
			"	mov		lr, r4								\n"
			"	ldmia	r0!, {r4-r11}						\n"	// load context of new thread
#endif	// __FPU_PRESENT == 1 && __FPU_USED == 1
			"	msr		PSP, r0								\n"
			"												\n"
			"	bx		lr									\n"	// return to new thread
	);

	__builtin_unreachable();
}
<commit_msg>ARMv7-M, PendSV_Handler(): formatting change<commit_after>/**
 * \file
 * \brief PendSV_Handler() for ARMv7-M (Cortex-M3 / Cortex-M4)
 *
 * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-03-19
 */

#include "distortos/scheduler/getScheduler.hpp"
#include "distortos/scheduler/Scheduler.hpp"

#include "distortos/chip/CMSIS-proxy.h"

/*---------------------------------------------------------------------------------------------------------------------+
| global functions
+---------------------------------------------------------------------------------------------------------------------*/

/**
 * \brief Wrapper for void* distortos::scheduler::getScheduler().switchContext(void*)
 *
 * \param [in] stackPointer is the current value of current thread's stack pointer
 *
 * \return new thread's stack pointer
 */

extern "C" void* schedulerSwitchContextWrapper(void* const stackPointer)
{
	return distortos::scheduler::getScheduler().switchContext(stackPointer);
}

/**
 * \brief PendSV_Handler() for ARMv7-M (Cortex-M3 / Cortex-M4)
 *
 * Performs the context switch.
 */

extern "C" __attribute__ ((naked)) void PendSV_Handler()
{
	asm volatile
	(
			"	mrs			r0, PSP							\n"
#if __FPU_PRESENT == 1 && __FPU_USED == 1
			"	stmdb		r0!, {r4-r11, lr}				\n"	// save context of current thread
#else
			"	stmdb		r0!, {r4-r11}					\n"	// save context of current thread
			"	mov			r4, lr							\n"
#endif	// __FPU_PRESENT == 1 && __FPU_USED == 1
			"												\n"
			"	bl			schedulerSwitchContextWrapper	\n"	// switch context
			"												\n"
#if __FPU_PRESENT == 1 && __FPU_USED == 1
			"	ldmia		r0!, {r4-r11, lr}				\n"	// load context of new thread
#else
			"	mov			lr, r4							\n"
			"	ldmia		r0!, {r4-r11}					\n"	// load context of new thread
#endif	// __FPU_PRESENT == 1 && __FPU_USED == 1
			"	msr			PSP, r0							\n"
			"												\n"
			"	bx			lr								\n"	// return to new thread
	);

	__builtin_unreachable();
}
<|endoftext|>


<commit_before>

#include <iostream>
//#include <boost/bind.hpp>
//
//#include <boost/test/included/unit_test.hpp>

#include <FFLLAPI.h>
#include <DefuzzVarObj.h>
#include <FFLLBase.h>
#include <FuzzyModelBase.h>
#include <FuzzyVariableBase.h>
#include <FuzzyOutVariable.h>
#include <RuleArray.h>
#include <MemberFuncTrap.h>
#include <MemberFuncTri.h>
#include <MemberFuncSCurve.h>
#include <MemberFuncSingle.h>
#include <FuzzySetBase.h>

int main( int argc, char* argv[] )
{
	FuzzyModelBase* testModel = new FuzzyModelBase();// = new FuzzyModelBase();
	testModel->init(); //create model with empty rule array
	//const Char* c = model->get_model_name();

	testModel->FuzzyModelBase::set_defuzz_method(0); // set DEFUZZ_COG method
	testModel->FuzzyModelBase::set_inference_method(0);
	testModel->FuzzyModelBase::set_composition_method(0);

	//FuzzyModelBase* pmodel = &model;

	std::wstring name1(L"inputVariable1");
	const wchar_t* szInputVariable1 = name1.c_str();

	std::wstring name2(L"outVariable1");
	const wchar_t* szOutVariable1 = name2.c_str();

	std::wstring name3(L"inputVariable2");
	const wchar_t* szInputVariable2 = name3.c_str();

	FuzzyVariableBase* inputVar1 = new FuzzyVariableBase(testModel);// create new inputVar
	int i = inputVar1->init(szInputVariable1, 34.5, 45.3, true);//left x value, right x value? 	// if no name is passed in name it "Variable 0"
//	ASSERT(i == -1);
	FuzzyVariableBase* inputVar2  = new FuzzyVariableBase(testModel);
	int k = inputVar2->init(szInputVariable2, 34.5, 45.3, true);
//	ASSERT(k == -1);
	FuzzyOutVariable* outVariable1 = new FuzzyOutVariable(testModel); // create new outVar
	int j = outVariable1->init(szOutVariable1, 23.4, 56.5, true); //return 0 if success
//	ASSERT(j == -1);

	testModel->add_input_variable(szInputVariable1, 34.5, 45.3, true);
	testModel->add_input_variable(szInputVariable1, 34.5, 45.3, true);
	testModel->add_output_variable(szOutVariable1, 23.4, 56.5, true);

	// set atributes for InputVariable1

	inputVar1->set_dom_array_count(100); // discrete y
	inputVar1->set_x_array_count(100); //discrete x

	inputVar1->set_index(0);

	// FuzzySets for InputVariable1
	FuzzySetBase* set1Var1 = new FuzzySetBase(inputVar1);
	// Set attributes for set1Var1

	FuzzySetBase* set2Var1 = new FuzzySetBase(inputVar1);
	FuzzySetBase* set3Var1 = new FuzzySetBase(inputVar1);

	// FuzzySets for InputVariable2
	FuzzySetBase* set1Var2 = new FuzzySetBase(inputVar2);
	FuzzySetBase* set2Var2 = new FuzzySetBase(inputVar2);
	FuzzySetBase* set3Var2 = new FuzzySetBase(inputVar2);

	// Membership functions for sets in InputVariable1

	MemberFuncTrap* functionTrap1 = new MemberFuncTrap(set1Var1);

	DOMType* arrayDegreeOfMembership = new DOMType[];
//	arrayDegreeOfMembership = (1,2,4,5,6,7,8,9,8,7,6,5,4,3,2,1);

	//FuzzyVariableBase *var = testModel->get_var(OUTPUT_IDX);

	// this code used for automaic create model from api

}<commit_msg> - продолжение теста<commit_after>

#include <iostream>
//#include <boost/bind.hpp>
//
//#include <boost/test/included/unit_test.hpp>

#include <FFLLAPI.h>
#include <DefuzzVarObj.h>
#include <FFLLBase.h>
#include <FuzzyModelBase.h>
#include <FuzzyVariableBase.h>
#include <FuzzyOutVariable.h>
#include <RuleArray.h>
#include <MemberFuncTrap.h>
#include <MemberFuncTri.h>
#include <MemberFuncSCurve.h>
#include <MemberFuncSingle.h>
#include <FuzzySetBase.h>

int main( int argc, char* argv[] )
{
	FuzzyModelBase* testModel = new FuzzyModelBase();// = new FuzzyModelBase();
	testModel->init(); //create model with empty rule array
	//const Char* c = model->get_model_name();

	testModel->FuzzyModelBase::set_defuzz_method(0); // set DEFUZZ_COG method
	testModel->FuzzyModelBase::set_inference_method(0);
	testModel->FuzzyModelBase::set_composition_method(0);

	//FuzzyModelBase* pmodel = &model;

	std::wstring name1(L"inputVariable1");
	const wchar_t* szInputVariable1 = name1.c_str();

	std::wstring name2(L"outVariable1");
	const wchar_t* szOutVariable1 = name2.c_str();

	std::wstring name3(L"inputVariable2");
	const wchar_t* szInputVariable2 = name3.c_str();

	std::wstring nameSet(L"set1Var1");
	wchar_t* wset_name1 = convert_to_wide_char("set1Var1");

	FuzzyVariableBase* inputVar1 = new FuzzyVariableBase(testModel);// create new inputVar
	int i = inputVar1->init(szInputVariable1, 34.5, 45.3, true);//left x value, right x value? 	// if no name is passed in name it "Variable 0"
	inputVar1->add_set(inputVar1->new_set(wset_name1,25,inputVar1,0,30,2));

	inputVar1->set_x_array_count(100);
//	inputVar1->set_right_x(25);
//	inputVar1->set_ramp(1,0,0);
	//inputVar1->set_dom_array_count(20);
//	inputVar1->set_left_x(0);

//	ASSERT(i == -1);
	FuzzyVariableBase* inputVar2  = new FuzzyVariableBase(testModel);
	int k = inputVar2->init(szInputVariable2, 34.5, 45.3, true);
//	ASSERT(k == -1);
	FuzzyOutVariable* outVariable1 = new FuzzyOutVariable(testModel); // create new outVar
	int j = outVariable1->init(szOutVariable1, 23.4, 56.5, true); //return 0 if success
//	ASSERT(j == -1);

	testModel->add_input_variable(szInputVariable1, 34.5, 45.3, true);
	testModel->add_input_variable(szInputVariable1, 34.5, 45.3, true);
	testModel->add_output_variable(szOutVariable1, 23.4, 56.5, true);

	// set atributes for InputVariable1

	inputVar1->set_dom_array_count(100); // discrete y
	inputVar1->set_x_array_count(100); //discrete x

	inputVar1->set_index(0);

	// FuzzySets for InputVariable1
	FuzzySetBase* set1Var1 = new FuzzySetBase(inputVar1);
	// Set attributes for set1Var1

	FuzzySetBase* set2Var1 = new FuzzySetBase(inputVar1);
	FuzzySetBase* set3Var1 = new FuzzySetBase(inputVar1);

	// FuzzySets for InputVariable2
	FuzzySetBase* set1Var2 = new FuzzySetBase(inputVar2);
	FuzzySetBase* set2Var2 = new FuzzySetBase(inputVar2);
	FuzzySetBase* set3Var2 = new FuzzySetBase(inputVar2);

	// Membership functions for sets in InputVariable1

	MemberFuncTrap* functionTrap1 = new MemberFuncTrap(set1Var1);
	functionTrap1->init();
	functionTrap1->set_ramp(1,0); // RAMP_NA
	functionTrap1->init();
	functionTrap1->set_node(0,25,0);
	functionTrap1->set_node(1,27,1);  // 4 point for trap
	functionTrap1->set_node(2,30,1);
	functionTrap1->set_node(3,32,0);

	wchar_t* wset_name = convert_to_wide_char("Set1Var1");
//	FuzzySetBase* set = new_set(wset_name, 0, inputVar1, 3, 0, 2);

	functionTrap1->get_start_x();
	functionTrap1->get_end_x();
	functionTrap1->get_node_x(2);
	functionTrap1->get_node_y(2);
	functionTrap1->get_ramp();
	functionTrap1->get_center_x();
//	functionTrap1->get_dom();
//	functionTrap1->get_value();

	DOMType* arrayDegreeOfMembership = new DOMType[];
//	arrayDegreeOfMembership = (1,2,4,5,6,7,8,9,8,7,6,5,4,3,2,1);

	//FuzzyVariableBase *var = testModel->get_var(OUTPUT_IDX);

	// this code used for automaic create model from api

}<|endoftext|>


<commit_before>/*
 *   CrissCross
 *   A multi-purpose cross-platform library.
 *
 *   A product of Uplink Laboratories.
 *
 *   (c) 2006-2007 Steven Noonan.
 *   Licensed under the New BSD License.
 *
 */

#include <crisscross/universal_include.h>

#include <crisscross/debug.h>
#include <crisscross/core_io.h>
#include <crisscross/system.h>

using namespace CrissCross::System;

namespace CrissCross
{
	namespace IO
	{
		CoreIOReader::CoreIOReader ( FILE * _fileBuffer, bool _isUnicode, LineEndingType _lnEnding ):
		m_fileInputPointer ( _fileBuffer ),
		m_unicode ( _isUnicode )
		{
			SetLineEndings ( _lnEnding );
		}

		CoreIOReader::~CoreIOReader ()
		{
		}

		bool
		CoreIOReader::EndOfFile ()
		{
			CoreAssert ( this != NULL );

			if ( !m_fileInputPointer )
				return true;

			return ( feof ( m_fileInputPointer ) != 0 );
		}

		void
		CoreIOReader::Flush ()
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return;

		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif
			fflush ( m_fileInputPointer );
		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif
		}

		bool
		CoreIOReader::IsOpen ()
		{
			CoreAssert ( this != NULL );

			if ( m_fileInputPointer == NULL )
				return false;
			else
				return true;
		}

		int
		CoreIOReader::Forward ( cc_int64_t _position )
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;
			int res = Seek ( _position, SEEK_CUR );
			return ( res == 0 );
		}

		cc_int64_t
		CoreIOReader::Length ()
		{
			CoreAssert ( this != NULL );
			CoreAssert ( IsOpen() );

		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif
			fpos64_t lastpos, endpos;
#ifdef TARGET_OS_WINDOWS
			lastpos = _ftelli64 ( m_fileInputPointer );
			_fseeki64 ( m_fileInputPointer, 0, SEEK_END );
			endpos = _ftelli64 ( m_fileInputPointer );
			_fseeki64 ( m_fileInputPointer, lastpos, SEEK_SET );
#elif defined ( TARGET_OS_MACOSX )
			fgetpos ( m_fileInputPointer, &lastpos );
			fseek ( m_fileInputPointer, 0, SEEK_END );
			fgetpos ( m_fileInputPointer, &endpos );
			fsetpos ( m_fileInputPointer, &lastpos );
#else
			fgetpos64 ( m_fileInputPointer, &lastpos );
			fseeko64 ( m_fileInputPointer, 0, SEEK_END );
			fgetpos64 ( m_fileInputPointer, &endpos );
			fsetpos64 ( m_fileInputPointer, &lastpos );
#endif
		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif

		#if defined ( TARGET_OS_WINDOWS ) || defined ( TARGET_OS_MACOSX ) || defined ( TARGET_OS_FREEBSD ) || \
			defined ( TARGET_OS_NETBSD ) || defined ( TARGET_OS_OPENBSD ) || defined ( TARGET_COMPILER_CYGWIN )
			return endpos;
		#elif defined ( TARGET_OS_LINUX )
			return endpos.__pos;
		#endif
		}

		int
		CoreIOReader::Read ( char *_destination )
		{
			CoreAssert ( this != NULL );
			CoreAssert ( _destination != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;

		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif
			*_destination = (char)fgetc ( m_fileInputPointer );
		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif
			return sizeof(char);
		}

		int
		CoreIOReader::Read ( char *_buffer, size_t _bufferLength, size_t _bufferIndex, size_t _count )
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;

			size_t retval;

			CoreAssert ( _buffer != NULL );
			CoreAssert ( _bufferLength - _bufferIndex > _count );
			CoreAssert ( _count > 0 );
		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif
			retval = fread ( &_buffer[_bufferIndex], sizeof(char), _count, m_fileInputPointer );
			_buffer[_bufferIndex + retval] = '\x0';
		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif
			return (int)retval;
		}

		int
		CoreIOReader::ReadLine ( char *_buffer, size_t _bufferLength )
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;

		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif

			// We use fgets because it detects line endings.
			_buffer[0] = '\x0';
			fgets ( _buffer, (int)_bufferLength, m_fileInputPointer );

			// Detect line endings.
			char *endl = NULL;
			char *cr = strchr ( _buffer, '\r' );
			char *lf = strchr ( _buffer, '\n' );
			char *crlf = strstr ( _buffer, "\r\n" );
			if ( crlf ) { SetLineEndings ( CC_LN_CRLF ); endl = crlf; }
			else if ( cr ) { SetLineEndings ( CC_LN_CR ); endl = cr; }
			else if ( lf ) { SetLineEndings ( CC_LN_LF ); endl = lf; }

			if ( endl )
				*endl = '\x0';

		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif

			return (int)strlen ( _buffer );
		}

		int
		CoreIOReader::ReadLine ( std::string &_string )
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;

		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif
			char c = (char) fgetc ( m_fileInputPointer );

			if ( c == (char)EOF )
				return 0;

			static std::string buffer;

			while ( c != (char)EOF && c != '\n' )
			{
				buffer += c;
				c = (char)fgetc ( m_fileInputPointer );
			}

			int len = (int)buffer.length ();

			if ( len && buffer[len - 1] == '\r' )
				buffer.resize ( len - 1 );

		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif

			_string = buffer;

			return (int)_string.length() * sizeof ( char );
		}

		int
		CoreIOReader::Seek ( cc_int64_t _position, int _origin )
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;

		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif
#ifdef TARGET_OS_WINDOWS
			int res = _fseeki64 ( m_fileInputPointer, _position, _origin );
#else
			int res = fseeko64 ( m_fileInputPointer, _position, _origin );
#endif
		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif
			return res;
		}

		int
		CoreIOReader::Seek ( cc_int64_t _position )
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;
			int res = Seek ( _position, SEEK_SET );
			return ( res == 0 );
		}

		CrissCross::Errors
		CoreIOReader::SetLineEndings ( LineEndingType _ending )
		{
			CoreAssert ( this != NULL );

			if ( _ending == CC_LN_NATIVE )
			{
		#if defined ( TARGET_OS_WINDOWS )
				_ending = CC_LN_CRLF;
		#elif defined ( TARGET_OS_LINUX ) || defined ( TARGET_OS_MACOSX ) || defined ( TARGET_OS_FREEBSD ) || defined ( TARGET_OS_NETBSD ) || defined ( TARGET_OS_OPENBSD )
				_ending = CC_LN_LF;
		#else
		#        error You are not using a supported OS.
		#endif
			}

			switch ( _ending )
			{
			case CC_LN_CR:
				sprintf ( m_lineEnding, "\r" );
				break;
			case CC_LN_LF:
				sprintf ( m_lineEnding, "\n" );
				break;
			case CC_LN_CRLF:
				sprintf ( m_lineEnding, "\r\n" );
				break;
			default:
				return CC_ERR_BADPARAMETER;
			}
			return CC_ERR_NONE;
		}
	}
}
<commit_msg>Correcting data types issue.<commit_after>/*
 *   CrissCross
 *   A multi-purpose cross-platform library.
 *
 *   A product of Uplink Laboratories.
 *
 *   (c) 2006-2007 Steven Noonan.
 *   Licensed under the New BSD License.
 *
 */

#include <crisscross/universal_include.h>

#include <crisscross/debug.h>
#include <crisscross/core_io.h>
#include <crisscross/system.h>

using namespace CrissCross::System;

namespace CrissCross
{
	namespace IO
	{
		CoreIOReader::CoreIOReader ( FILE * _fileBuffer, bool _isUnicode, LineEndingType _lnEnding ):
		m_fileInputPointer ( _fileBuffer ),
		m_unicode ( _isUnicode )
		{
			SetLineEndings ( _lnEnding );
		}

		CoreIOReader::~CoreIOReader ()
		{
		}

		bool
		CoreIOReader::EndOfFile ()
		{
			CoreAssert ( this != NULL );

			if ( !m_fileInputPointer )
				return true;

			return ( feof ( m_fileInputPointer ) != 0 );
		}

		void
		CoreIOReader::Flush ()
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return;

		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif
			fflush ( m_fileInputPointer );
		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif
		}

		bool
		CoreIOReader::IsOpen ()
		{
			CoreAssert ( this != NULL );

			if ( m_fileInputPointer == NULL )
				return false;
			else
				return true;
		}

		int
		CoreIOReader::Forward ( cc_int64_t _position )
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;
			int res = Seek ( _position, SEEK_CUR );
			return ( res == 0 );
		}

		cc_int64_t
		CoreIOReader::Length ()
		{
			CoreAssert ( this != NULL );
			CoreAssert ( IsOpen() );

		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif
			fpos64_t lastpos, endpos;
#ifdef TARGET_OS_WINDOWS
			lastpos = _ftelli64 ( m_fileInputPointer );
			_fseeki64 ( m_fileInputPointer, 0, SEEK_END );
			endpos = _ftelli64 ( m_fileInputPointer );
			_fseeki64 ( m_fileInputPointer, lastpos, SEEK_SET );
#elif defined ( TARGET_OS_MACOSX )
			fgetpos ( m_fileInputPointer, &lastpos );
			fseek ( m_fileInputPointer, 0, SEEK_END );
			fgetpos ( m_fileInputPointer, &endpos );
			fsetpos ( m_fileInputPointer, &lastpos );
#else
			fgetpos64 ( m_fileInputPointer, &lastpos );
			fseeko64 ( m_fileInputPointer, 0, SEEK_END );
			fgetpos64 ( m_fileInputPointer, &endpos );
			fsetpos64 ( m_fileInputPointer, &lastpos );
#endif
		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif

		#if defined ( TARGET_OS_WINDOWS ) || defined ( TARGET_OS_MACOSX ) || defined ( TARGET_OS_FREEBSD ) || \
			defined ( TARGET_OS_NETBSD ) || defined ( TARGET_OS_OPENBSD ) || defined ( TARGET_COMPILER_CYGWIN )
			return endpos;
		#elif defined ( TARGET_OS_LINUX )
			return endpos.__pos;
		#endif
		}

		int
		CoreIOReader::Read ( char *_destination )
		{
			CoreAssert ( this != NULL );
			CoreAssert ( _destination != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;

		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif
			*_destination = (char)fgetc ( m_fileInputPointer );
		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif
			return sizeof(char);
		}

		int
		CoreIOReader::Read ( char *_buffer, size_t _bufferLength, size_t _bufferIndex, size_t _count )
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;

			size_t retval;

			CoreAssert ( _buffer != NULL );
			CoreAssert ( _bufferLength - _bufferIndex > _count );
			CoreAssert ( _count > 0 );
		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif
			retval = fread ( &_buffer[_bufferIndex], sizeof(char), _count, m_fileInputPointer );
			_buffer[_bufferIndex + retval] = '\x0';
		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif
			return (int)retval;
		}

		int
		CoreIOReader::ReadLine ( char *_buffer, size_t _bufferLength )
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;

		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif

			// We use fgets because it detects line endings.
			_buffer[0] = '\x0';
			fgets ( _buffer, (int)_bufferLength, m_fileInputPointer );

			// Detect line endings.
			char *endl = NULL;
			char *cr = strchr ( _buffer, '\r' );
			char *lf = strchr ( _buffer, '\n' );
			char *crlf = strstr ( _buffer, "\r\n" );
			if ( crlf ) { SetLineEndings ( CC_LN_CRLF ); endl = crlf; }
			else if ( cr ) { SetLineEndings ( CC_LN_CR ); endl = cr; }
			else if ( lf ) { SetLineEndings ( CC_LN_LF ); endl = lf; }

			if ( endl )
				*endl = '\x0';

		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif

			return (int)strlen ( _buffer );
		}

		int
		CoreIOReader::ReadLine ( std::string &_string )
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;

		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif
			char c = (char) fgetc ( m_fileInputPointer );

			if ( c == (char)EOF )
				return 0;

			static std::string buffer;

			while ( c != (char)EOF && c != '\n' )
			{
				buffer += c;
				c = (char)fgetc ( m_fileInputPointer );
			}

			int len = (int)buffer.length ();

			if ( len && buffer[len - 1] == '\r' )
				buffer.resize ( len - 1 );

		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif

			_string = buffer;

			return (int)_string.length() * sizeof ( char );
		}

		int
		CoreIOReader::Seek ( cc_int64_t _position, int _origin )
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;

		#ifndef __GNUC__
			m_ioMutex.Lock ();
		#endif
#ifdef TARGET_OS_WINDOWS
			int res = _fseeki64 ( m_fileInputPointer, _position, _origin );
#elif defined ( TARGET_OS_MACOSX )
			int res = fseek ( m_fileInputPointer, _position, _origin );
#endif
			int res = fseeko64 ( m_fileInputPointer, _position, _origin );
#endif
		#ifndef __GNUC__
			m_ioMutex.Unlock ();
		#endif
			return res;
		}

		int
		CoreIOReader::Seek ( cc_int64_t _position )
		{
			CoreAssert ( this != NULL );
			if ( !IsOpen() ) return CC_ERR_INVALID_BUFFER;
			int res = Seek ( _position, SEEK_SET );
			return ( res == 0 );
		}

		CrissCross::Errors
		CoreIOReader::SetLineEndings ( LineEndingType _ending )
		{
			CoreAssert ( this != NULL );

			if ( _ending == CC_LN_NATIVE )
			{
		#if defined ( TARGET_OS_WINDOWS )
				_ending = CC_LN_CRLF;
		#elif defined ( TARGET_OS_LINUX ) || defined ( TARGET_OS_MACOSX ) || defined ( TARGET_OS_FREEBSD ) || defined ( TARGET_OS_NETBSD ) || defined ( TARGET_OS_OPENBSD )
				_ending = CC_LN_LF;
		#else
		#        error You are not using a supported OS.
		#endif
			}

			switch ( _ending )
			{
			case CC_LN_CR:
				sprintf ( m_lineEnding, "\r" );
				break;
			case CC_LN_LF:
				sprintf ( m_lineEnding, "\n" );
				break;
			case CC_LN_CRLF:
				sprintf ( m_lineEnding, "\r\n" );
				break;
			default:
				return CC_ERR_BADPARAMETER;
			}
			return CC_ERR_NONE;
		}
	}
}
<|endoftext|>