<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 "otbReciprocalHAlphaImageFilter.h"
#include "otbReciprocalBarnesDecompImageFilter.h"
#include "otbReciprocalHuynenDecompImageFilter.h"
#include "otbReciprocalPauliDecompImageFilter.h"

#include "otbSinclairReciprocalImageFilter.h"
#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
#include "otbPerBandVectorImageFilter.h"
#include "itkMeanImageFilter.h"
#include "otbNRIBandImagesToOneNComplexBandsImage.h"

namespace otb
{
namespace Wrapper
{

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

  typedef otb::Functor::SinclairToReciprocalCoherencyMatrixFunctor<ComplexDoubleImageType::PixelType,
                                    ComplexDoubleImageType::PixelType,
                                    ComplexDoubleImageType::PixelType,
                                    ComplexDoubleVectorImageType::PixelType>								FunctorType;

  typedef SinclairReciprocalImageFilter<ComplexDoubleImageType,
											 ComplexDoubleImageType,
											 ComplexDoubleImageType,
											 ComplexDoubleVectorImageType,
											 FunctorType > 												    SRFilterType;

  typedef itk::MeanImageFilter<ComplexDoubleImageType, ComplexDoubleImageType>                                         MeanFilterType;
  typedef otb::PerBandVectorImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType, MeanFilterType>    PerBandMeanFilterType;
  //typedef otb::NRIBandImagesToOneNComplexBandsImage<DoubleVectorImageType, ComplexDoubleVectorImageType>               NRITOOneCFilterType;

  typedef otb::ReciprocalHAlphaImageFilter<ComplexDoubleVectorImageType, DoubleVectorImageType> 			           HAFilterType;
  typedef otb::ReciprocalBarnesDecompImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType>           BarnesFilterType;
  typedef otb::ReciprocalHuynenDecompImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType>           HuynenFilterType;
  //typedef otb::ReciprocalPauliDecompImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType>            PauliFilterType;

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

  itkTypeMacro(SARDecompositions, otb::Application);

private:
  void DoInit()
  {
    SetName("SARDecompositions");
    SetDescription("From one-band complex images (each one related to an element of the Sinclair matrix), returns the selected decomposition.");

    // Documentation
    SetDocName("SARDecompositions");
    SetDocLongDescription("From one-band complex images (HH, HV, VH, VV), returns the selected decomposition.\n \n"
                          "All the decompositions implemented are intended for the mono-static case (transmitter and receiver are co-located).\n"
                          "There are two kinds of decomposition : coherent ones and incoherent ones.\n"
                          "In the coherent case, only the Pauli decomposition is available.\n"
                          "In the incoherent case, there the decompositions available : Huynen, Barnes, and H-alpha-A.\n"
						  "User must provide three one-band complex images HH, HV or VH, and VV (mono-static case <=> HV = VH).\n"
						  "Incoherent decompositions consist in averaging 3x3 complex coherency/covariance matrices; the user must provide the size of the averaging window, thanks to the parameter inco.kernelsize.\n "
						  );

    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("SARPolarMatrixConvert, SARPolarSynth");

    AddDocTag(Tags::SAR);

    AddParameter(ParameterType_ComplexInputImage,  "inhh",   "Input Image");
    SetParameterDescription("inhh", "Input image (HH)");

    AddParameter(ParameterType_ComplexInputImage,  "inhv",   "Input Image");
    SetParameterDescription("inhv", "Input image (HV)");
    MandatoryOff("inhv");

    AddParameter(ParameterType_ComplexInputImage,  "invh",   "Input Image");
    SetParameterDescription("invh", "Input image (VH)");
    MandatoryOff("invh");

    AddParameter(ParameterType_ComplexInputImage,  "invv",   "Input Image");
    SetParameterDescription("invv", "Input image (VV)");

    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
    SetParameterDescription("out", "Output image");

    AddParameter(ParameterType_Choice, "decomp", "Decompositions");
    AddChoice("decomp.haa","H-alpha-A incoherent decomposition");
    SetParameterDescription("decomp.haa","H-alpha-A incoherent decomposition");
    AddChoice("decomp.barnes","Barnes incoherent decomposition");
    SetParameterDescription("decomp.barnes","Barnes incoherent decomposition");

    AddParameter(ParameterType_Group,"inco","Incoherent decompositions");
    SetParameterDescription("inco","This group allows setting parameters related to the incoherent decompositions.");

    AddParameter(ParameterType_Int, "inco.kernelsize",   "Kernel size for spatial incoherent averaging.");
    SetParameterDescription("inco.kernelsize", "Minute (0-59)");
    SetMinimumParameterIntValue("inco.kernelsize", 1);
    SetDefaultParameterInt("inco.kernelsize", 3);
    MandatoryOff("inco.kernelsize");

    AddRAMParameter();

    // Default values
    SetDefaultParameterInt("decomp", 0); // H-alpha-A

    // Doc example parameter settings
    SetDocExampleParameterValue("inhh", "HH.tif");
	SetDocExampleParameterValue("invh", "VH.tif");
	SetDocExampleParameterValue("invv", "VV.tif");
	SetDocExampleParameterValue("decomp", "haa");
    SetDocExampleParameterValue("out", "HaA.tif");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {

	bool inhv = HasUserValue("inhv");
	bool invh = HasUserValue("invh");

	if ( (!inhv) && (!invh) )
	  otbAppLogFATAL( << "Parameter inhv or invh not set. Please provide a HV or a VH complex image.");

    m_SRFilter = SRFilterType::New();
	m_HAFilter = HAFilterType::New();
	m_MeanFilter = PerBandMeanFilterType::New();
    MeanFilterType::InputSizeType radius;
    m_BarnesFilter = BarnesFilterType::New();

    switch (GetParameterInt("decomp"))
      {
		case 0: // H-alpha-A

		if (inhv)
		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
	    else if (invh)
		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));

		m_SRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
		m_SRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));

        radius.Fill( GetParameterInt("inco.kernelsize") );
        m_MeanFilter->GetFilter()->SetRadius(radius);

		m_MeanFilter->SetInput(m_SRFilter->GetOutput());
		m_HAFilter->SetInput(m_MeanFilter->GetOutput());
		SetParameterOutputImage("out", m_HAFilter->GetOutput() );

		break;

		case 1: // Barnes

		if (inhv)
		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
	    else if (invh)
		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));

		m_SRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
		m_SRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));

        radius.Fill( GetParameterInt("inco.kernelsize") );
        m_MeanFilter->GetFilter()->SetRadius(radius);

		m_MeanFilter->SetInput(m_SRFilter->GetOutput());
		m_BarnesFilter->SetInput(m_MeanFilter->GetOutput());
		SetParameterComplexOutputImage("out", m_BarnesFilter->GetOutput() );

		break;
	  }

  }

  //MCPSFilterType::Pointer m_MCPSFilter;
  SRFilterType::Pointer m_SRFilter;
  HAFilterType::Pointer m_HAFilter;
  BarnesFilterType::Pointer m_BarnesFilter;
  PerBandMeanFilterType::Pointer m_MeanFilter;

};

} //end namespace Wrapper
} //end namespace otb

OTB_APPLICATION_EXPORT(otb::Wrapper::SARDecompositions)
<commit_msg>ENH: SARDecompositions app now outputs complex images<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 "otbReciprocalHAlphaImageFilter.h"
#include "otbReciprocalBarnesDecompImageFilter.h"
#include "otbReciprocalHuynenDecompImageFilter.h"
#include "otbReciprocalPauliDecompImageFilter.h"

#include "otbSinclairReciprocalImageFilter.h"
#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
#include "otbPerBandVectorImageFilter.h"
#include "itkMeanImageFilter.h"
#include "otbNRIBandImagesToOneNComplexBandsImage.h"

namespace otb
{
namespace Wrapper
{

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

  typedef otb::Functor::SinclairToReciprocalCoherencyMatrixFunctor<ComplexDoubleImageType::PixelType,
                                    ComplexDoubleImageType::PixelType,
                                    ComplexDoubleImageType::PixelType,
                                    ComplexDoubleVectorImageType::PixelType>								FunctorType;

  typedef SinclairReciprocalImageFilter<ComplexDoubleImageType,
											 ComplexDoubleImageType,
											 ComplexDoubleImageType,
											 ComplexDoubleVectorImageType,
											 FunctorType > 												    SRFilterType;

  typedef itk::MeanImageFilter<ComplexDoubleImageType, ComplexDoubleImageType>                                         MeanFilterType;
  typedef otb::PerBandVectorImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType, MeanFilterType>    PerBandMeanFilterType;
  //typedef otb::NRIBandImagesToOneNComplexBandsImage<DoubleVectorImageType, ComplexDoubleVectorImageType>               NRITOOneCFilterType;

  typedef otb::ReciprocalHAlphaImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType> 			           HAFilterType;
  typedef otb::ReciprocalBarnesDecompImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType>           BarnesFilterType;
  typedef otb::ReciprocalHuynenDecompImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType>           HuynenFilterType;
  //typedef otb::ReciprocalPauliDecompImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType>            PauliFilterType;

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

  itkTypeMacro(SARDecompositions, otb::Application);

private:
  void DoInit()
  {
    SetName("SARDecompositions");
    SetDescription("From one-band complex images (each one related to an element of the Sinclair matrix), returns the selected decomposition.");

    // Documentation
    SetDocName("SARDecompositions");
    SetDocLongDescription("From one-band complex images (HH, HV, VH, VV), returns the selected decomposition.\n \n"
                          "All the decompositions implemented are intended for the mono-static case (transmitter and receiver are co-located).\n"
                          "There are two kinds of decomposition : coherent ones and incoherent ones.\n"
                          "In the coherent case, only the Pauli decomposition is available.\n"
                          "In the incoherent case, there the decompositions available : Huynen, Barnes, and H-alpha-A.\n"
						  "User must provide three one-band complex images HH, HV or VH, and VV (mono-static case <=> HV = VH).\n"
						  "Incoherent decompositions consist in averaging 3x3 complex coherency/covariance matrices; the user must provide the size of the averaging window, thanks to the parameter inco.kernelsize.\n "
						  );

    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("SARPolarMatrixConvert, SARPolarSynth");

    AddDocTag(Tags::SAR);

    AddParameter(ParameterType_ComplexInputImage,  "inhh",   "Input Image");
    SetParameterDescription("inhh", "Input image (HH)");

    AddParameter(ParameterType_ComplexInputImage,  "inhv",   "Input Image");
    SetParameterDescription("inhv", "Input image (HV)");
    MandatoryOff("inhv");

    AddParameter(ParameterType_ComplexInputImage,  "invh",   "Input Image");
    SetParameterDescription("invh", "Input image (VH)");
    MandatoryOff("invh");

    AddParameter(ParameterType_ComplexInputImage,  "invv",   "Input Image");
    SetParameterDescription("invv", "Input image (VV)");

    AddParameter(ParameterType_ComplexOutputImage, "out",  "Output Image");
    SetParameterDescription("out", "Output image");

    AddParameter(ParameterType_Choice, "decomp", "Decompositions");
    AddChoice("decomp.haa","H-alpha-A incoherent decomposition");
    SetParameterDescription("decomp.haa","H-alpha-A incoherent decomposition");
    AddChoice("decomp.barnes","Barnes incoherent decomposition");
    SetParameterDescription("decomp.barnes","Barnes incoherent decomposition");

    AddParameter(ParameterType_Group,"inco","Incoherent decompositions");
    SetParameterDescription("inco","This group allows setting parameters related to the incoherent decompositions.");

    AddParameter(ParameterType_Int, "inco.kernelsize",   "Kernel size for spatial incoherent averaging.");
    SetParameterDescription("inco.kernelsize", "Minute (0-59)");
    SetMinimumParameterIntValue("inco.kernelsize", 1);
    SetDefaultParameterInt("inco.kernelsize", 3);
    MandatoryOff("inco.kernelsize");

    AddRAMParameter();

    // Default values
    SetDefaultParameterInt("decomp", 0); // H-alpha-A

    // Doc example parameter settings
    SetDocExampleParameterValue("inhh", "HH.tif");
	SetDocExampleParameterValue("invh", "VH.tif");
	SetDocExampleParameterValue("invv", "VV.tif");
	SetDocExampleParameterValue("decomp", "haa");
    SetDocExampleParameterValue("out", "HaA.tif");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {

	bool inhv = HasUserValue("inhv");
	bool invh = HasUserValue("invh");

	if ( (!inhv) && (!invh) )
	  otbAppLogFATAL( << "Parameter inhv or invh not set. Please provide a HV or a VH complex image.");

    m_SRFilter = SRFilterType::New();
	m_HAFilter = HAFilterType::New();
	m_MeanFilter = PerBandMeanFilterType::New();
    MeanFilterType::InputSizeType radius;
    m_BarnesFilter = BarnesFilterType::New();

    switch (GetParameterInt("decomp"))
      {
		case 0: // H-alpha-A

		if (inhv)
		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
	    else if (invh)
		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));

		m_SRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
		m_SRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));

        radius.Fill( GetParameterInt("inco.kernelsize") );
        m_MeanFilter->GetFilter()->SetRadius(radius);

		m_MeanFilter->SetInput(m_SRFilter->GetOutput());
		m_HAFilter->SetInput(m_MeanFilter->GetOutput());
		SetParameterComplexOutputImage("out", m_HAFilter->GetOutput() );

		break;

		case 1: // Barnes

		if (inhv)
		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
	    else if (invh)
		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));

		m_SRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
		m_SRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));

        radius.Fill( GetParameterInt("inco.kernelsize") );
        m_MeanFilter->GetFilter()->SetRadius(radius);

		m_MeanFilter->SetInput(m_SRFilter->GetOutput());
		m_BarnesFilter->SetInput(m_MeanFilter->GetOutput());
		SetParameterComplexOutputImage("out", m_BarnesFilter->GetOutput() );

		break;
	  }

  }

  //MCPSFilterType::Pointer m_MCPSFilter;
  SRFilterType::Pointer m_SRFilter;
  HAFilterType::Pointer m_HAFilter;
  BarnesFilterType::Pointer m_BarnesFilter;
  PerBandMeanFilterType::Pointer m_MeanFilter;

};

} //end namespace Wrapper
} //end namespace otb

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


<commit_before>//===-- SICodeEmitter.cpp - SI Code Emitter -------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The SI code emitter produces machine code that can be executed directly on
// the GPU device.
//
//===----------------------------------------------------------------------===//

#include "AMDGPU.h"
#include "AMDGPUCodeEmitter.h"
#include "AMDGPUUtil.h"
#include "SIInstrInfo.h"
#include "SIMachineFunctionInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetMachine.h"

#include <map>
#include <stdio.h>

#define LITERAL_REG 255
#define VGPR_BIT(src_idx) (1ULL << (9 * src_idx - 1))
using namespace llvm;

namespace {

  class SICodeEmitter : public MachineFunctionPass, public AMDGPUCodeEmitter {

  private:
    static char ID;
    formatted_raw_ostream &_OS;
    const TargetMachine *TM;

    //Program Info
    unsigned MaxSGPR;
    unsigned MaxVGPR;
    unsigned CurrentInstrIndex;
    std::map<int, unsigned> BBIndexes;

    void InitProgramInfo(MachineFunction &MF);
    void EmitState(MachineFunction & MF);
    void emitInstr(MachineInstr &MI);

    void outputBytes(uint64_t value, unsigned bytes);
    unsigned GPRAlign(const MachineInstr &MI, unsigned OpNo, unsigned shift)
                                                                      const;

  public:
    SICodeEmitter(formatted_raw_ostream &OS) : MachineFunctionPass(ID),
        _OS(OS), TM(NULL), MaxSGPR(0), MaxVGPR(0), CurrentInstrIndex(0) { }
    const char *getPassName() const { return "SI Code Emitter"; }
    bool runOnMachineFunction(MachineFunction &MF);

    /// getMachineOpValue - Return the encoding for MO
    virtual uint64_t getMachineOpValue(const MachineInstr &MI,
                                       const MachineOperand &MO) const;

    /// GPR4AlignEncode - Encoding for when 4 consectuive registers are used
    virtual unsigned GPR4AlignEncode(const MachineInstr  &MI, unsigned OpNo)
                                                                      const;

    /// GPR2AlignEncode - Encoding for when 2 consecutive registers are used
    virtual unsigned GPR2AlignEncode(const MachineInstr &MI, unsigned OpNo)
                                                                      const;
    /// i32LiteralEncode - Encode an i32 literal this is used as an operand
    /// for an instruction in place of a register.
    virtual uint64_t i32LiteralEncode(const MachineInstr &MI, unsigned OpNo)
                                                                      const;
    /// SMRDmemriEncode - Encoding for SMRD indexed loads
    virtual uint32_t SMRDmemriEncode(const MachineInstr &MI, unsigned OpNo)
                                                                     const;

    /// VOPPostEncode - Post-Encoder method for VOP instructions
    virtual uint64_t VOPPostEncode(const MachineInstr &MI,
                                   uint64_t Value) const;
  };
}

char SICodeEmitter::ID = 0;

FunctionPass *llvm::createSICodeEmitterPass(formatted_raw_ostream &OS) {
  return new SICodeEmitter(OS);
}

void SICodeEmitter::EmitState(MachineFunction & MF) {
  SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>();
  outputBytes(MaxSGPR + 1, 4);
  outputBytes(MaxVGPR + 1, 4);
  outputBytes(MFI->spi_ps_input_addr, 4);
}

void SICodeEmitter::InitProgramInfo(MachineFunction &MF) {
  unsigned InstrIndex = 0;
  bool VCCUsed = false;
  const SIRegisterInfo * RI =
                static_cast<const SIRegisterInfo*>(TM->getRegisterInfo());

  for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
                                                  BB != BB_E; ++BB) {
    MachineBasicBlock &MBB = *BB;
    BBIndexes[MBB.getNumber()] = InstrIndex;
    InstrIndex += MBB.size();
    for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
                                                    I != E; ++I) {
      MachineInstr &MI = *I;

      unsigned numOperands = MI.getNumOperands();
      for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) {
        MachineOperand & MO = MI.getOperand(op_idx);
        unsigned maxUsed;
        unsigned width = 0;
        bool isSGPR = false;
        unsigned reg;
        unsigned hwReg;
        if (!MO.isReg()) {
          continue;
        }
        reg = MO.getReg();
        if (reg == AMDGPU::VCC) {
          VCCUsed = true;
          continue;
        }
        if (AMDGPU::SReg_32RegClass.contains(reg)) {
          isSGPR = true;
          width = 1;
        } else if (AMDGPU::VReg_32RegClass.contains(reg)) {
          isSGPR = false;
          width = 1;
        } else if (AMDGPU::SReg_64RegClass.contains(reg)) {
          isSGPR = true;
          width = 2;
        } else if (AMDGPU::VReg_64RegClass.contains(reg)) {
          isSGPR = false;
          width = 2;
        } else if (AMDGPU::SReg_128RegClass.contains(reg)) {
          isSGPR = true;
          width = 4;
        } else if (AMDGPU::VReg_128RegClass.contains(reg)) {
          isSGPR = false;
          width = 4;
        } else if (AMDGPU::SReg_256RegClass.contains(reg)) {
          isSGPR = true;
          width = 8;
        } else {
          assert("!Unknown register class");
        }
        hwReg = RI->getHWRegNum(reg);
        maxUsed = hwReg + width - 1;
        if (isSGPR) {
          MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR;
        } else {
          MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR;
        }
      }
    }
  }
  if (VCCUsed) {
    MaxSGPR += 2;
  }
}

bool SICodeEmitter::runOnMachineFunction(MachineFunction &MF)
{
  TM = &MF.getTarget();
  const AMDGPUSubtarget &STM = TM->getSubtarget<AMDGPUSubtarget>();

  if (STM.dumpCode()) {
    MF.dump();
  }

  InitProgramInfo(MF);

  EmitState(MF);

  for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
                                                  BB != BB_E; ++BB) {
    MachineBasicBlock &MBB = *BB;
    for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
                                                      I != E; ++I) {
      MachineInstr &MI = *I;
      if (MI.getOpcode() != AMDGPU::KILL && MI.getOpcode() != AMDGPU::RETURN) {
        emitInstr(MI);
        CurrentInstrIndex++;
      }
    }
  }
  // Emit S_END_PGM
  MachineInstr * End = BuildMI(MF, DebugLoc(),
                               TM->getInstrInfo()->get(AMDGPU::S_ENDPGM));
  emitInstr(*End);
  return false;
}

void SICodeEmitter::emitInstr(MachineInstr &MI)
{
  const SIInstrInfo * SII = static_cast<const SIInstrInfo*>(TM->getInstrInfo());

  uint64_t hwInst = getBinaryCodeForInstr(MI);

  if ((hwInst & 0xffffffff) == 0xffffffff) {
    fprintf(stderr, "Unsupported Instruction: \n");
    MI.dump();
    abort();
  }

  unsigned bytes = SII->getEncodingBytes(MI);
  outputBytes(hwInst, bytes);
}

uint64_t SICodeEmitter::getMachineOpValue(const MachineInstr &MI,
                                          const MachineOperand &MO) const
{
  const SIRegisterInfo * RI =
                static_cast<const SIRegisterInfo*>(TM->getRegisterInfo());

  switch(MO.getType()) {
  case MachineOperand::MO_Register:
    return RI->getBinaryCode(MO.getReg());

  case MachineOperand::MO_Immediate:
    return MO.getImm();

  case MachineOperand::MO_FPImmediate:
    // XXX: Not all instructions can use inline literals
    // XXX: We should make sure this is a 32-bit constant
    return LITERAL_REG | (MO.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue() << 32);

  case MachineOperand::MO_MachineBasicBlock:
    return (*BBIndexes.find(MI.getParent()->getNumber())).second -
           CurrentInstrIndex - 1;
  default:
    llvm_unreachable("Encoding of this operand type is not supported yet.");
    break;
  }
}

unsigned SICodeEmitter::GPRAlign(const MachineInstr &MI, unsigned OpNo,
    unsigned shift) const
{
  const SIRegisterInfo * RI =
                static_cast<const SIRegisterInfo*>(TM->getRegisterInfo());
  unsigned regCode = RI->getHWRegNum(MI.getOperand(OpNo).getReg());
  return regCode >> shift;
}

unsigned SICodeEmitter::GPR4AlignEncode(const MachineInstr &MI,
    unsigned OpNo) const
{
  return GPRAlign(MI, OpNo, 2);
}

unsigned SICodeEmitter::GPR2AlignEncode(const MachineInstr &MI,
    unsigned OpNo) const
{
  return GPRAlign(MI, OpNo, 1);
}

uint64_t SICodeEmitter::i32LiteralEncode(const MachineInstr &MI,
    unsigned OpNo) const
{
  return LITERAL_REG | (MI.getOperand(OpNo).getImm() << 32);
}

#define SMRD_OFFSET_MASK 0xff
#define SMRD_IMM_SHIFT 8
#define SMRD_SBASE_MASK 0x3f
#define SMRD_SBASE_SHIFT 9
/// SMRDmemriEncode - This function is responsibe for encoding the offset
/// and the base ptr for SMRD instructions it should return a bit string in
/// this format:
///
/// OFFSET = bits{7-0}
/// IMM    = bits{8}
/// SBASE  = bits{14-9}
///
uint32_t SICodeEmitter::SMRDmemriEncode(const MachineInstr &MI,
    unsigned OpNo) const
{
  uint32_t encoding;

  const MachineOperand &OffsetOp = MI.getOperand(OpNo + 1);

  //XXX: Use this function for SMRD loads with register offsets
  assert(OffsetOp.isImm());

  encoding =
      (getMachineOpValue(MI, OffsetOp) & SMRD_OFFSET_MASK)
    | (1 << SMRD_IMM_SHIFT) //XXX If the Offset is a register we shouldn't set this bit
    | ((GPR2AlignEncode(MI, OpNo) & SMRD_SBASE_MASK) << SMRD_SBASE_SHIFT)
    ;

  return encoding;
}

/// Set the "VGPR" bit for VOP args that can take either a VGPR or a SGPR.
/// XXX: It would be nice if we could handle this without a PostEncode function.
uint64_t SICodeEmitter::VOPPostEncode(const MachineInstr &MI,
    uint64_t Value) const
{
  const SIInstrInfo * SII = static_cast<const SIInstrInfo*>(TM->getInstrInfo());
  unsigned encodingType = SII->getEncodingType(MI);
  unsigned numSrcOps;
  unsigned vgprBitOffset;

  if (encodingType == SIInstrEncodingType::VOP3) {
    numSrcOps = 3;
    vgprBitOffset = 32;
  } else {
    numSrcOps = 1;
    vgprBitOffset = 0;
  }

  // Add one to skip over the destination reg operand.
  for (unsigned opIdx = 1; opIdx < numSrcOps + 1; opIdx++) {
    if (!MI.getOperand(opIdx).isReg()) {
      continue;
    }
    unsigned reg = MI.getOperand(opIdx).getReg();
    if (AMDGPU::VReg_32RegClass.contains(reg)
        || AMDGPU::VReg_64RegClass.contains(reg)) {
      Value |= (VGPR_BIT(opIdx)) << vgprBitOffset;
    }
  }
  return Value;
}

void SICodeEmitter::outputBytes(uint64_t value, unsigned bytes)
{
  for (unsigned i = 0; i < bytes; i++) {
    _OS.write((uint8_t) ((value >> (8 * i)) & 0xff));
  }
}
<commit_msg>radeon/llvm: fix fp immediates on SI<commit_after>//===-- SICodeEmitter.cpp - SI Code Emitter -------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The SI code emitter produces machine code that can be executed directly on
// the GPU device.
//
//===----------------------------------------------------------------------===//

#include "AMDGPU.h"
#include "AMDGPUCodeEmitter.h"
#include "AMDGPUUtil.h"
#include "SIInstrInfo.h"
#include "SIMachineFunctionInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetMachine.h"

#include <map>
#include <stdio.h>

#define LITERAL_REG 255
#define VGPR_BIT(src_idx) (1ULL << (9 * src_idx - 1))
using namespace llvm;

namespace {

  class SICodeEmitter : public MachineFunctionPass, public AMDGPUCodeEmitter {

  private:
    static char ID;
    formatted_raw_ostream &_OS;
    const TargetMachine *TM;

    //Program Info
    unsigned MaxSGPR;
    unsigned MaxVGPR;
    unsigned CurrentInstrIndex;
    std::map<int, unsigned> BBIndexes;

    void InitProgramInfo(MachineFunction &MF);
    void EmitState(MachineFunction & MF);
    void emitInstr(MachineInstr &MI);

    void outputBytes(uint64_t value, unsigned bytes);
    unsigned GPRAlign(const MachineInstr &MI, unsigned OpNo, unsigned shift)
                                                                      const;

  public:
    SICodeEmitter(formatted_raw_ostream &OS) : MachineFunctionPass(ID),
        _OS(OS), TM(NULL), MaxSGPR(0), MaxVGPR(0), CurrentInstrIndex(0) { }
    const char *getPassName() const { return "SI Code Emitter"; }
    bool runOnMachineFunction(MachineFunction &MF);

    /// getMachineOpValue - Return the encoding for MO
    virtual uint64_t getMachineOpValue(const MachineInstr &MI,
                                       const MachineOperand &MO) const;

    /// GPR4AlignEncode - Encoding for when 4 consectuive registers are used
    virtual unsigned GPR4AlignEncode(const MachineInstr  &MI, unsigned OpNo)
                                                                      const;

    /// GPR2AlignEncode - Encoding for when 2 consecutive registers are used
    virtual unsigned GPR2AlignEncode(const MachineInstr &MI, unsigned OpNo)
                                                                      const;
    /// i32LiteralEncode - Encode an i32 literal this is used as an operand
    /// for an instruction in place of a register.
    virtual uint64_t i32LiteralEncode(const MachineInstr &MI, unsigned OpNo)
                                                                      const;
    /// SMRDmemriEncode - Encoding for SMRD indexed loads
    virtual uint32_t SMRDmemriEncode(const MachineInstr &MI, unsigned OpNo)
                                                                     const;

    /// VOPPostEncode - Post-Encoder method for VOP instructions
    virtual uint64_t VOPPostEncode(const MachineInstr &MI,
                                   uint64_t Value) const;
  };
}

char SICodeEmitter::ID = 0;

FunctionPass *llvm::createSICodeEmitterPass(formatted_raw_ostream &OS) {
  return new SICodeEmitter(OS);
}

void SICodeEmitter::EmitState(MachineFunction & MF) {
  SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>();
  outputBytes(MaxSGPR + 1, 4);
  outputBytes(MaxVGPR + 1, 4);
  outputBytes(MFI->spi_ps_input_addr, 4);
}

void SICodeEmitter::InitProgramInfo(MachineFunction &MF) {
  unsigned InstrIndex = 0;
  bool VCCUsed = false;
  const SIRegisterInfo * RI =
                static_cast<const SIRegisterInfo*>(TM->getRegisterInfo());

  for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
                                                  BB != BB_E; ++BB) {
    MachineBasicBlock &MBB = *BB;
    BBIndexes[MBB.getNumber()] = InstrIndex;
    InstrIndex += MBB.size();
    for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
                                                    I != E; ++I) {
      MachineInstr &MI = *I;

      unsigned numOperands = MI.getNumOperands();
      for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) {
        MachineOperand & MO = MI.getOperand(op_idx);
        unsigned maxUsed;
        unsigned width = 0;
        bool isSGPR = false;
        unsigned reg;
        unsigned hwReg;
        if (!MO.isReg()) {
          continue;
        }
        reg = MO.getReg();
        if (reg == AMDGPU::VCC) {
          VCCUsed = true;
          continue;
        }
        if (AMDGPU::SReg_32RegClass.contains(reg)) {
          isSGPR = true;
          width = 1;
        } else if (AMDGPU::VReg_32RegClass.contains(reg)) {
          isSGPR = false;
          width = 1;
        } else if (AMDGPU::SReg_64RegClass.contains(reg)) {
          isSGPR = true;
          width = 2;
        } else if (AMDGPU::VReg_64RegClass.contains(reg)) {
          isSGPR = false;
          width = 2;
        } else if (AMDGPU::SReg_128RegClass.contains(reg)) {
          isSGPR = true;
          width = 4;
        } else if (AMDGPU::VReg_128RegClass.contains(reg)) {
          isSGPR = false;
          width = 4;
        } else if (AMDGPU::SReg_256RegClass.contains(reg)) {
          isSGPR = true;
          width = 8;
        } else {
          assert("!Unknown register class");
        }
        hwReg = RI->getHWRegNum(reg);
        maxUsed = hwReg + width - 1;
        if (isSGPR) {
          MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR;
        } else {
          MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR;
        }
      }
    }
  }
  if (VCCUsed) {
    MaxSGPR += 2;
  }
}

bool SICodeEmitter::runOnMachineFunction(MachineFunction &MF)
{
  TM = &MF.getTarget();
  const AMDGPUSubtarget &STM = TM->getSubtarget<AMDGPUSubtarget>();

  if (STM.dumpCode()) {
    MF.dump();
  }

  InitProgramInfo(MF);

  EmitState(MF);

  for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
                                                  BB != BB_E; ++BB) {
    MachineBasicBlock &MBB = *BB;
    for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
                                                      I != E; ++I) {
      MachineInstr &MI = *I;
      if (MI.getOpcode() != AMDGPU::KILL && MI.getOpcode() != AMDGPU::RETURN) {
        emitInstr(MI);
        CurrentInstrIndex++;
      }
    }
  }
  // Emit S_END_PGM
  MachineInstr * End = BuildMI(MF, DebugLoc(),
                               TM->getInstrInfo()->get(AMDGPU::S_ENDPGM));
  emitInstr(*End);
  return false;
}

void SICodeEmitter::emitInstr(MachineInstr &MI)
{
  const SIInstrInfo * SII = static_cast<const SIInstrInfo*>(TM->getInstrInfo());

  uint64_t hwInst = getBinaryCodeForInstr(MI);

  if ((hwInst & 0xffffffff) == 0xffffffff) {
    fprintf(stderr, "Unsupported Instruction: \n");
    MI.dump();
    abort();
  }

  unsigned bytes = SII->getEncodingBytes(MI);
  outputBytes(hwInst, bytes);
}

uint64_t SICodeEmitter::getMachineOpValue(const MachineInstr &MI,
                                          const MachineOperand &MO) const
{
  const SIRegisterInfo * RI =
                static_cast<const SIRegisterInfo*>(TM->getRegisterInfo());

  switch(MO.getType()) {
  case MachineOperand::MO_Register:
    return RI->getBinaryCode(MO.getReg());

  case MachineOperand::MO_Immediate:
    return MO.getImm();

  case MachineOperand::MO_FPImmediate:
    // XXX: Not all instructions can use inline literals
    // XXX: We should make sure this is a 32-bit constant
    return LITERAL_REG;

  case MachineOperand::MO_MachineBasicBlock:
    return (*BBIndexes.find(MI.getParent()->getNumber())).second -
           CurrentInstrIndex - 1;
  default:
    llvm_unreachable("Encoding of this operand type is not supported yet.");
    break;
  }
}

unsigned SICodeEmitter::GPRAlign(const MachineInstr &MI, unsigned OpNo,
    unsigned shift) const
{
  const SIRegisterInfo * RI =
                static_cast<const SIRegisterInfo*>(TM->getRegisterInfo());
  unsigned regCode = RI->getHWRegNum(MI.getOperand(OpNo).getReg());
  return regCode >> shift;
}

unsigned SICodeEmitter::GPR4AlignEncode(const MachineInstr &MI,
    unsigned OpNo) const
{
  return GPRAlign(MI, OpNo, 2);
}

unsigned SICodeEmitter::GPR2AlignEncode(const MachineInstr &MI,
    unsigned OpNo) const
{
  return GPRAlign(MI, OpNo, 1);
}

uint64_t SICodeEmitter::i32LiteralEncode(const MachineInstr &MI,
    unsigned OpNo) const
{
  return LITERAL_REG | (MI.getOperand(OpNo).getImm() << 32);
}

#define SMRD_OFFSET_MASK 0xff
#define SMRD_IMM_SHIFT 8
#define SMRD_SBASE_MASK 0x3f
#define SMRD_SBASE_SHIFT 9
/// SMRDmemriEncode - This function is responsibe for encoding the offset
/// and the base ptr for SMRD instructions it should return a bit string in
/// this format:
///
/// OFFSET = bits{7-0}
/// IMM    = bits{8}
/// SBASE  = bits{14-9}
///
uint32_t SICodeEmitter::SMRDmemriEncode(const MachineInstr &MI,
    unsigned OpNo) const
{
  uint32_t encoding;

  const MachineOperand &OffsetOp = MI.getOperand(OpNo + 1);

  //XXX: Use this function for SMRD loads with register offsets
  assert(OffsetOp.isImm());

  encoding =
      (getMachineOpValue(MI, OffsetOp) & SMRD_OFFSET_MASK)
    | (1 << SMRD_IMM_SHIFT) //XXX If the Offset is a register we shouldn't set this bit
    | ((GPR2AlignEncode(MI, OpNo) & SMRD_SBASE_MASK) << SMRD_SBASE_SHIFT)
    ;

  return encoding;
}

/// Set the "VGPR" bit for VOP args that can take either a VGPR or a SGPR.
/// XXX: It would be nice if we could handle this without a PostEncode function.
uint64_t SICodeEmitter::VOPPostEncode(const MachineInstr &MI,
    uint64_t Value) const
{
  const SIInstrInfo * SII = static_cast<const SIInstrInfo*>(TM->getInstrInfo());
  unsigned encodingType = SII->getEncodingType(MI);
  unsigned numSrcOps;
  unsigned vgprBitOffset;

  if (encodingType == SIInstrEncodingType::VOP3) {
    numSrcOps = 3;
    vgprBitOffset = 32;
  } else {
    numSrcOps = 1;
    vgprBitOffset = 0;
  }

  // Add one to skip over the destination reg operand.
  for (unsigned opIdx = 1; opIdx < numSrcOps + 1; opIdx++) {
    const MachineOperand &MO = MI.getOperand(opIdx);
    switch(MO.getType()) {
    case MachineOperand::MO_Register:
      {
        unsigned reg = MI.getOperand(opIdx).getReg();
        if (AMDGPU::VReg_32RegClass.contains(reg)
            || AMDGPU::VReg_64RegClass.contains(reg)) {
          Value |= (VGPR_BIT(opIdx)) << vgprBitOffset;
        }
      }
      break;

    case MachineOperand::MO_FPImmediate:
      // XXX: Not all instructions can use inline literals
      // XXX: We should make sure this is a 32-bit constant
      Value |= (MO.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue() << 32);
      continue;

    default:
      break;
    }
  }
  return Value;
}

void SICodeEmitter::outputBytes(uint64_t value, unsigned bytes)
{
  for (unsigned i = 0; i < bytes; i++) {
    _OS.write((uint8_t) ((value >> (8 * i)) & 0xff));
  }
}
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Leiden University Medical Center, Erasmus University Medical
 *  Center and contributors
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "selxSuperElastixFilterCustomComponents.h"

#include "selxNiftyregReadImageComponent.h"
#include "selxNiftyregWriteImageComponent.h"
#include "selxNiftyregWriteImageComponent.h"
#include "selxItkToNiftiImageSourceComponent.h"
#include "selxNiftiToItkImageSinkComponent.h"
#include "selxItkImageSourceComponent.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "selxNiftyregf3dComponent.h"
#include "selxNiftyregSplineToDisplacementFieldComponent.h"
#include "selxDisplacementFieldNiftiToItkImageSinkComponent.h"
#include "selxNiftyregAladinComponent.h"
#include "selxDataManager.h"
#include "gtest/gtest.h"

#include "_reg_tools.h"

namespace selx
{
class NiftyregDisplacementTest : public ::testing::Test
{
public:

  typedef Blueprint::Pointer BlueprintPointer;
  typedef Blueprint::ParameterMapType ParameterMapType;
  typedef Blueprint::ParameterValueType ParameterValueType;
  typedef DataManager DataManagerType;

  /** register all example components */
  typedef TypeList<
    ItkToNiftiImageSourceComponent< 2, float >,
    NiftiToItkImageSinkComponent< 2, float >,
    ItkImageSourceComponent< 2, float >,
    ItkToNiftiImageSourceComponent< 3, float >,
    NiftiToItkImageSinkComponent< 3, float >,
    ItkImageSourceComponent< 3, float >,
    DisplacementFieldNiftiToItkImageSinkComponent< 2, float>> RegisterComponents;

  typedef SuperElastixFilterCustomComponents< RegisterComponents > SuperElastixFilterType;

  virtual void SetUp()
  {
    // Instantiate SuperElastixFilter before each test and
    // register the components we want to have available in SuperElastix
    superElastixFilter = SuperElastixFilterCustomComponents< RegisterComponents >::New();
    dataManager = DataManagerType::New();
    logger = Logger::New();
    logger->AddStream("cout", std::cout);
    logger->SetLogLevel(LogLevel::TRC);
  }

  virtual void TearDown()
  {
    // Unregister all components after each test
    itk::ObjectFactoryBase::UnRegisterAllFactories();
    // Delete the SuperElastixFilter after each test
    superElastixFilter = nullptr;
  }

  BlueprintPointer blueprint;
  Logger::Pointer logger;
  SuperElastixFilterBase::Pointer superElastixFilter;
  DataManagerType::Pointer dataManager;
};

TEST_F( NiftyregDisplacementTest, displacement_conversion )
{
  /** make example blueprint configuration */

  // Generate an nifti image on the fly
  int size = 64;
  int dim[8] = {3, size, size, size, 1, 1, 1, 1};
  nifti_image *floating_image = nifti_make_new_nim(dim, NIFTI_TYPE_FLOAT32, true);
  float *imgPtr = static_cast<float>(floating_image->data);
  for(int i=0; i<floating_image->nvox; ++i){
    imgPtr[i] = i;
  }
  // Create a deformation field that embeds an affine transformation
  mat44 affine;
  affine.m[0][0]=0.8.f;affine.m[0][1]=0.1f;affine.m[0][2]=0.1f;affine.m[0][3]=-5.f;
  affine.m[0][0]=0.1f;affine.m[0][1]=1.1f;affine.m[0][2]=0.1f;affine.m[0][3]=1.f;
  affine.m[0][0]=0.1f;affine.m[0][1]=0.1f;affine.m[0][2]=1.f;affine.m[0][3]=5.f;
  affine.m[0][0]=0.f;affine.m[0][1]=0.f;affine.m[0][2]=0.f;affine.m[3][3]=1.f;
  nifti_image *transFieldImage = nifti_copy_nim_info(floating_image);
  transFieldImage->dim[0]=transFieldImage->ndim=5;
  transFieldImage->dim[1]=transFieldImage->nx=floating_image->nx;
  transFieldImage->dim[2]=transFieldImage->ny=floating_image->ny;
  transFieldImage->dim[3]=transFieldImage->nz=floating_image->nz;
  transFieldImage->dim[4]=transFieldImage->nt=1;
  transFieldImage->pixdim[4]=transFieldImage->dt=1.0;
  transFieldImage->dim[5]=transFieldImage->nu=floating_image->nz>1?3:2;
  transFieldImage->dim[6]=transFieldImage->nv=1;
  transFieldImage->dim[7]=transFieldImage->nw=1;
  transFieldImage->nvox =(size_t)transFieldImage->nx*
        transFieldImage->ny*transFieldImage->nz*
        transFieldImage->nt*transFieldImage->nu;
  transFieldImage->scl_slope=1.f;
  transFieldImage->scl_inter=0.f;
   transFieldImage->datatype = NIFTI_TYPE_FLOAT32;
   transFieldImage->nbyper = sizeof(float);
  transFieldImage->data = (void *)calloc(transFieldImage->nvox, transFieldImage->nbyper);
  reg_affine_getDeformationField(&affine,
                                 transFieldImage);

  // Apply the deformation to the floating image
  nifti_image* warped_image = nifti_copy_nim_info(floating_image);
  warped_image->data = (void *)calloc(warped_image->nvox,warped_image->nbyper);
  reg_resampleImage(floating_image,
                    warped_image,
                    transFieldImage,
                    NULL,
                    0, // nearest neighbour interpolation
                    0); // 0 padding

  // Convert the deformation field into a displacement field
  reg_getDisplacementFromDeformation(transFieldImage);

  // NEED TO ADD THE SELX PART HERE

  // NEED TO ADD THE COMPARISON HERE

  nifti_image_free(floating_image);
  nifti_image_free(warped_image);
  nifti_image_free(transFieldImage);
}
}
<commit_msg>WIP: Extended unit test with itk warp comparision #257<commit_after>/*=========================================================================
 *
 *  Copyright Leiden University Medical Center, Erasmus University Medical
 *  Center and contributors
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "selxSuperElastixFilterCustomComponents.h"

#include "selxNiftyregReadImageComponent.h"
#include "selxNiftyregWriteImageComponent.h"
#include "selxNiftyregWriteImageComponent.h"
#include "selxItkToNiftiImageSourceComponent.h"
#include "selxNiftiToItkImageSinkComponent.h"
#include "selxItkImageSourceComponent.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "selxNiftyregf3dComponent.h"
#include "selxNiftyregSplineToDisplacementFieldComponent.h"
#include "selxDisplacementFieldNiftiToItkImageSinkComponent.h"
#include "selxNiftyregAladinComponent.h"

#include "itkDisplacementFieldTransform.h"
#include "itkResampleImageFilter.h"
#include "itkNearestNeighborInterpolateImageFunction.h"
#include <itkTestingComparisonImageFilter.h>

#include "selxDataManager.h"
#include "gtest/gtest.h"

#include "_reg_tools.h"

namespace selx
{
class NiftyregDisplacementTest : public ::testing::Test
{
public:

  typedef Blueprint::Pointer BlueprintPointer;
  typedef Blueprint::ParameterMapType ParameterMapType;
  typedef Blueprint::ParameterValueType ParameterValueType;
  typedef DataManager DataManagerType;

  /** register all example components */
  typedef TypeList<
    ItkToNiftiImageSourceComponent< 2, float >,
    NiftiToItkImageSinkComponent< 2, float >,
    ItkImageSourceComponent< 2, float >,
    ItkToNiftiImageSourceComponent< 3, float >,
    NiftiToItkImageSinkComponent< 3, float >,
    ItkImageSourceComponent< 3, float >,
    DisplacementFieldNiftiToItkImageSinkComponent< 2, float>> RegisterComponents;

  typedef SuperElastixFilterCustomComponents< RegisterComponents > SuperElastixFilterType;

  virtual void SetUp()
  {
    // Instantiate SuperElastixFilter before each test and
    // register the components we want to have available in SuperElastix
    superElastixFilter = SuperElastixFilterCustomComponents< RegisterComponents >::New();
    dataManager = DataManagerType::New();
    logger = Logger::New();
    logger->AddStream("cout", std::cout);
    logger->SetLogLevel(LogLevel::TRC);
  }

  virtual void TearDown()
  {
    // Unregister all components after each test
    itk::ObjectFactoryBase::UnRegisterAllFactories();
    // Delete the SuperElastixFilter after each test
    superElastixFilter = nullptr;
  }

  BlueprintPointer blueprint;
  Logger::Pointer logger;
  SuperElastixFilterBase::Pointer superElastixFilter;
  DataManagerType::Pointer dataManager;
};

TEST_F( NiftyregDisplacementTest, displacement_conversion )
{
  /** make example blueprint configuration */

  // Generate an nifti image on the fly
  int size = 64;
  int dim[8] = {3, size, size, size, 1, 1, 1, 1};
  nifti_image *floating_image = nifti_make_new_nim(dim, NIFTI_TYPE_FLOAT32, true);
  floating_image->qform_code = 1;
  float *imgPtr = static_cast<float*>(floating_image->data);
  for(int i=0; i<floating_image->nvox; ++i){
    imgPtr[i] = i;
  }
  // Create a deformation field that embeds an affine transformation
  mat44 affine;
  affine.m[0][0]=0.8f;affine.m[0][1]=0.1f;affine.m[0][2]=0.1f;affine.m[0][3]=-5.f;
  affine.m[1][0]=0.1f;affine.m[1][1]=1.1f;affine.m[1][2]=0.1f;affine.m[1][3]=1.f;
  affine.m[2][0]=0.1f;affine.m[2][1]=0.1f;affine.m[1][2]=1.f;affine.m[2][3]=5.f;
  affine.m[3][0]=0.f;affine.m[3][1]=0.f;affine.m[1][2]=0.f;affine.m[3][3]=1.f;
  reg_mat44_eye(&affine);
  nifti_image *transFieldImage = nifti_copy_nim_info(floating_image);
  transFieldImage->dim[0]=transFieldImage->ndim=5;
  transFieldImage->dim[1]=transFieldImage->nx=floating_image->nx;
  transFieldImage->dim[2]=transFieldImage->ny=floating_image->ny;
  transFieldImage->dim[3]=transFieldImage->nz=floating_image->nz;
  transFieldImage->dim[4]=transFieldImage->nt=1;
  transFieldImage->pixdim[4]=transFieldImage->dt=1.0;
  transFieldImage->dim[5]=transFieldImage->nu=floating_image->nz>1?3:2;
  transFieldImage->dim[6]=transFieldImage->nv=1;
  transFieldImage->dim[7]=transFieldImage->nw=1;
  transFieldImage->nvox =(size_t)transFieldImage->nx*
        transFieldImage->ny*transFieldImage->nz*
        transFieldImage->nt*transFieldImage->nu;
  transFieldImage->scl_slope=1.f;
  transFieldImage->scl_inter=0.f;
   transFieldImage->datatype = NIFTI_TYPE_FLOAT32;
   transFieldImage->nbyper = sizeof(float);
  transFieldImage->data = (void *)calloc(transFieldImage->nvox, transFieldImage->nbyper);
  reg_affine_getDeformationField(&affine,
                                 transFieldImage);

  // Apply the deformation to the floating image
  nifti_image* warped_image = nifti_copy_nim_info(floating_image);
  warped_image->data = (void *)calloc(warped_image->nvox,warped_image->nbyper);
  reg_resampleImage(floating_image,
                    warped_image,
                    transFieldImage,
                    NULL,
                    0, // nearest neighbour interpolation
                    0); // 0 padding

  // Convert the deformation field into a displacement field
  reg_getDisplacementFromDeformation(transFieldImage);
  float *dispPtrX = static_cast<float *>(transFieldImage->data);
  float *dispPtrY = static_cast<float *>(&dispPtrX[warped_image->nvox]);
  float *dispPtrZ = static_cast<float *>(&dispPtrY[warped_image->nvox]);
  for (int v = 0; v<warped_image->nvox; v++) {
	  dispPtrX[v] *= -1.f;
	  dispPtrY[v] *= -1.f;
  }

  reg_io_WriteImageFile(warped_image,"NiftyregDisplacementTest_displacement_conversion_nifty.nii");

  // NEED TO ADD THE SELX PART HERE

  using itkImageType = itk::Image<float, 3>;
  std::shared_ptr< nifti_image > nifti_floating_image(floating_image, nifti_image_free);
  auto itkImage = selx::NiftiToItkImage<itkImageType, float>::Convert(nifti_floating_image);
  using CoordRepType = float;

  using itkDisplacementType = itk::Image<itk::Vector<CoordRepType,3>, 3>;
  std::shared_ptr< nifti_image > nifti_transFieldImage(transFieldImage, nifti_image_free);
  auto itkDisplacementImage = selx::NiftiToItkImage<itkDisplacementType, float>::Convert(nifti_transFieldImage);

  using DisplacementFieldTransformType = itk::DisplacementFieldTransform< CoordRepType, 3 >;
  using DisplacementFieldTransformPointer = typename DisplacementFieldTransformType::Pointer;

  using ResampleImageFilterType = itk::ResampleImageFilter< itkImageType, itkImageType, CoordRepType >;
  using ResampleImageFilterPointer = typename ResampleImageFilterType::Pointer;

  using NearestNeighborInterpolatorType = itk::NearestNeighborInterpolateImageFunction<
	  itkImageType, typename itkImageType::PixelType>;
  using NearestNeighborInterpolatorTypePointer = typename NearestNeighborInterpolatorType::Pointer;

  auto displacementFieldTransform = DisplacementFieldTransformType::New();
  auto resampleImageFilter = ResampleImageFilterType::New();
  resampleImageFilter->SetInput(itkImage);
  resampleImageFilter->SetTransform(displacementFieldTransform.GetPointer());
  auto nearestNeighborInterpolator = NearestNeighborInterpolatorType::New();
  resampleImageFilter->SetInterpolator(nearestNeighborInterpolator);

  itkDisplacementImage->Update();
  displacementFieldTransform->SetDisplacementField(itkDisplacementImage);
  resampleImageFilter->SetOutputParametersFromImage(itkDisplacementImage);
  //resampleImageFilter->Update();
  auto itkwarped = resampleImageFilter->GetOutput();

  auto itkwriter = itk::ImageFileWriter<itkImageType>::New();
  itkwriter->SetInput(itkwarped);
  itkwriter->SetFileName("NiftyregDisplacementTest_displacement_conversion_itk.nii");
  itkwriter->Update();

  // NEED TO ADD THE COMPARISON HERE
  std::shared_ptr< nifti_image > nifti_warped_image(warped_image, nifti_image_free);
  auto itk_nifti_warped_image = selx::NiftiToItkImage<itkImageType, float>::Convert(nifti_warped_image);

  auto diff = itk::Testing::ComparisonImageFilter<itkImageType,itkImageType>::New();
  diff->SetValidInput(itk_nifti_warped_image);
  //diff->SetTestInput(itk_nifti_warped_image);
  //diff->SetValidInput(resampleImageFilter->GetOutput());
  diff->SetTestInput(resampleImageFilter->GetOutput());
  diff->SetDifferenceThreshold(0.0);
  //diff->SetToleranceRadius(radiusTolerance);
  diff->UpdateLargestPossibleRegion();
  bool differenceFailed = false;
  const double averageIntensityDifference = diff->GetTotalDifference();

  //nifti_image_free(floating_image);
  //nifti_image_free(warped_image);
  //nifti_image_free(transFieldImage);
}
}
<|endoftext|>


<commit_before>/* --------------------------------------------------------------------------

   MusicBrainz -- The Internet music metadatabase

   Copyright (C) 2000 Robert Kaye

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

     $Id$

----------------------------------------------------------------------------*/
#include <stdio.h>
#include "musicbrainz.h"
#include "queries.h"

struct Queries
{
    char *name, *value;
    int   numArgs;
    char *arg1, *arg2, *arg3, *arg4;
};

const char *SUBMIT_LYRICS_QUERY=
"   <MQ:Query>SubmitTrack</MQ:Query>\n"
"    <DC:Title>Big Time TWO</DC:Title>\n"
"    <DC:Creator>Peter another Gabriel</DC:Creator>\n"
"    <MM:Album>So des ca</MM:Album>\n"
"    <DC:Relation track=\"9\"/>\n"
"    <MM:SyncEvents>\n"
//"       <rdf:Description about=\"http://usenet4free.com?grp=alt.music.lyrics&art=26819\">\n"
"       <rdf:Description>\n"
"         <DC:Contributor>Red Hot Lyrics Man</DC:Contributor>\n"
"         <DC:Type type=\"lyrics\"/>\n"
"         <DC:Date>2000-07-27</DC:Date>\n"
"         <rdf:Seq>\n"
"            <rdf:li>\n"
"               <rdf:Description>\n"
"                  <MM:SyncText ts=\"00:02.451\">Hello World</MM:SyncText>\n"
"               </rdf:Description>\n"
"            </rdf:li>\n"
"            <rdf:li>\n"
"               <rdf:Description>\n"
"                  <MM:SyncText ts=\"00:06.882\">Sing along</MM:SyncText>\n"
"               </rdf:Description>\n"
"            </rdf:li>\n"
"            <rdf:li>\n"
"               <rdf:Description>\n"
"                  <MM:SyncText ts=\"01:03.096\">Make</MM:SyncText>\n"
"               </rdf:Description>\n"
"            </rdf:li>\n"
"            <rdf:li>\n"
"               <rdf:Description>\n"
"                  <MM:SyncText ts=\"01:09.478\">it</MM:SyncText>\n"
"               </rdf:Description>\n"
"            </rdf:li>\n"
"            <rdf:li>\n"
"               <rdf:Description>\n"
"                  <MM:SyncText ts=\"01:13.516\">all</MM:SyncText>\n"
"               </rdf:Description>\n"
"            </rdf:li>\n"
"            <rdf:li>\n"
"               <rdf:Description>\n"
"                  <MM:SyncText ts=\"01:41.744\">clear.</MM:SyncText>\n"
"               </rdf:Description>\n"
"            </rdf:li>\n"
"         </rdf:Seq>\n"
"       </rdf:Description>\n"
"    </MM:SyncEvents>\n";

Queries queries[] =
{
    { "GetCDInfoFromCDIndexId", MB_GetCDInfoFromCDIndexID,
      1, "CD Index ID", "", "", "" },
    { "FindArtist",             MB_FindArtistByName,
      1, "Artist Name", "", "", "" },
    { "FindTrack",              MB_FindTrackByName,
      3, "Track Name", "Album Name", "Artist Name", "" },
    { "FindAlbumsByArtist",     MB_FindAlbumsByArtistName,
      1, "Artist Name", "", "", "" },
    { "FindAlbum",              MB_FindAlbumByName,
      1, "Album Name", "", "", "" },
    { "FindDistinctGUID",       MB_FindDistinctGUID,
      2, "Track Name", "Artist Name", "", "" },
    { "GetArtist",              MB_GetArtistById ,
      1, "Artist ID", "", "", "" },
    { "GetAlbum",               MB_GetAlbumById ,
      1, "Album ID", "", "", "" },
    { "GetAlbumsByArtist",      MB_GetAlbumsByArtistId ,
      1, "Artist ID", "", "", "" },
    { "GetTrack",               MB_GetTrackById ,
      1, "Track ID", "", "", "" },
    { "GetTrackGUID",           MB_GetTrackByGUID ,
      1, "Track GUID", "", "", "" },
    { "GetSyncText",            MB_GetSyncTextById ,
      1, "Track ID", "", "", "" },
    { "GetCDInfo",              MB_GetCDInfo ,
      0, "", "", "", "" },
    { "GetCDTOC",               MB_GetCDTOC ,
      0, "", "", "", "" },
    { "AssociateCD",            MB_AssociateCD ,
      0, "", "", "", "" },
    { "\0",                     "\0", 0, "", "", "", "" }
};

#ifdef WIN32
#define strcasecmp stricmp
#endif

int main(void)
{
    MusicBrainz    o;
    string         error, data;
    bool           ret;
    Queries        *p;
    char           szLine[256], *szCmd, *ptr, szLast[100];
    string         xml, qarg, query, server;
    vector<string> args;

    // Set the server you want to use. Defaults to www.musicbrainz.org:80
    server = string("musicbrainz.eorbit.net");
    o.SetServer(server, 80);

    // Tell the client library to return data in ISO8859-1 and not UTF-8
    o.UseUTF8(0);

    // If you need to use a proxy, uncomment/edit the following line
    // as appropriate
    //o.SetProxy("proxy.mydomain.com", 80);

    for(;;)
    {
        query = "";
        printf("query> ");
        fflush(stdout);

        if (fgets(szLine, 255, stdin) < 0)
           break;

        if (strncmp(szLine, "!!", 2) == 0)
        {
            printf("%s\n", szLast);
            strcpy(szLine, szLast);
        }
        else
            strcpy(szLast, szLine);

        szLine[strlen(szLine) - 1] = 0;
        szCmd = strtok(szLine, " ");

        if (szCmd == NULL)
           continue;

        args.clear();
        for(;;)
        {
            ptr = strtok(NULL, " ");
            if (!ptr)
               break;

            if (*ptr == '\"' &&  !(*(ptr + strlen(ptr) - 1) == '\"'))
            {
               qarg = string(ptr + 1);
               for(;;)
               {
                   ptr = strtok(NULL, " ");
                   if (!ptr)
                      break;

                   if (*(ptr + strlen(ptr) - 1) == '\"')
                   {
                       *(ptr + strlen(ptr) - 1) = 0;
                       qarg += string(" ") + string(ptr);
                       ptr = (char *)qarg.c_str();
                       break;
                   }
                   qarg += string(" ") + string(ptr);
               }
               if (!ptr)
               {
                   continue;
               }
            }

            if (*ptr == '\"' &&  *(ptr + strlen(ptr) - 1) == '\"')
            {
               *(ptr + strlen(ptr) - 1) = 0;
               args.push_back(string(ptr + 1));
            }
            else
            {
               if (strcmp(ptr, "\"\"") == 0)
                  *ptr = 0;

               args.push_back(string(ptr));
            }
        }

        if (strncmp(szCmd, "bye", 3) == 0 ||
            strncmp(szCmd, "quit", 4) == 0 ||
            strncmp(szCmd, "exit", 4) == 0)
        {
            break;
        }

        if (strncmp(szCmd, "help", 4) == 0)
        {
            printf("Available commands:                Arguments:\n\n");
            for(p = queries; *p->name; p++)
            {
                printf("%-34s ", p->name);
                if (strlen(p->arg1))
                   printf("<%s> ", p->arg1);
                if (strlen(p->arg2))
                   printf("<%s> ", p->arg2);
                if (strlen(p->arg3))
                   printf("<%s> ", p->arg3);
                if (strlen(p->arg4))
                   printf("<%s> ", p->arg4);

                printf("\n");
            }
            printf("exit/quit/bye                      [quit]\n");
            printf("submit                             [get web submit URL]\n");
            printf("info                               [help on a command]\n");
            continue;
        }

        if (strncmp(szCmd, "lyrics", 6) == 0)
        {
            query = string(SUBMIT_LYRICS_QUERY);
        }

        if (strncmp(szCmd, "submit", 6) == 0)
        {
            string url;

            ret = o.GetWebSubmitURL(url);
            if (ret)
               printf("URL: %s\n", url.c_str());
            else
               printf("Could not determine web submit url.\n");

            continue;
        }

        if (strncmp(szCmd, "info", 4) == 0)
        {
            for(p = queries; p->name; p++)
            {
                if (strcasecmp(szCmd + 5, p->name) == 0)
                {
                   printf("usage: %s ", p->name);
                   if (strlen(p->arg1))
                      printf("<%s> ", p->arg1);
                   if (strlen(p->arg2))
                      printf("<%s> ", p->arg2);
                   if (strlen(p->arg3))
                      printf("<%s> ", p->arg3);
                   if (strlen(p->arg4))
                      printf("<%s> ", p->arg4);

                   printf("\n");
                   break;
                }
            }
            if (p->name == NULL)
               printf("No info available for %s\n", szCmd + 5);
            continue;
        }

        if (query.length() == 0)
        {
           for(p = queries; p->name; p++)
           {
               if (strcasecmp(szCmd, p->name) == 0)
                  break;
           }
           if (p->name == NULL)
           {
               printf("Unknown query.\n");
               continue;
           }
           query = string(p->value);
        }

        ret = o.Query(query, &args);
        if (!ret)
        {
             o.GetQueryError(error);
             printf("Query failed: %s\n", error.c_str());
             continue;
        }
        printf("Query ok. Items returned: %d\n", o.GetNumItems());

        o.GetResultRDF(xml);
        printf("Returned RDF object:\n\n%s\n", xml.c_str());
    }

    return 0;
}
<commit_msg>Fixed the server<commit_after>/* --------------------------------------------------------------------------

   MusicBrainz -- The Internet music metadatabase

   Copyright (C) 2000 Robert Kaye

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

     $Id$

----------------------------------------------------------------------------*/
#include <stdio.h>
#include "musicbrainz.h"
#include "queries.h"

struct Queries
{
    char *name, *value;
    int   numArgs;
    char *arg1, *arg2, *arg3, *arg4;
};

const char *SUBMIT_LYRICS_QUERY=
"   <MQ:Query>SubmitTrack</MQ:Query>\n"
"    <DC:Title>Big Time TWO</DC:Title>\n"
"    <DC:Creator>Peter another Gabriel</DC:Creator>\n"
"    <MM:Album>So des ca</MM:Album>\n"
"    <DC:Relation track=\"9\"/>\n"
"    <MM:SyncEvents>\n"
//"       <rdf:Description about=\"http://usenet4free.com?grp=alt.music.lyrics&art=26819\">\n"
"       <rdf:Description>\n"
"         <DC:Contributor>Red Hot Lyrics Man</DC:Contributor>\n"
"         <DC:Type type=\"lyrics\"/>\n"
"         <DC:Date>2000-07-27</DC:Date>\n"
"         <rdf:Seq>\n"
"            <rdf:li>\n"
"               <rdf:Description>\n"
"                  <MM:SyncText ts=\"00:02.451\">Hello World</MM:SyncText>\n"
"               </rdf:Description>\n"
"            </rdf:li>\n"
"            <rdf:li>\n"
"               <rdf:Description>\n"
"                  <MM:SyncText ts=\"00:06.882\">Sing along</MM:SyncText>\n"
"               </rdf:Description>\n"
"            </rdf:li>\n"
"            <rdf:li>\n"
"               <rdf:Description>\n"
"                  <MM:SyncText ts=\"01:03.096\">Make</MM:SyncText>\n"
"               </rdf:Description>\n"
"            </rdf:li>\n"
"            <rdf:li>\n"
"               <rdf:Description>\n"
"                  <MM:SyncText ts=\"01:09.478\">it</MM:SyncText>\n"
"               </rdf:Description>\n"
"            </rdf:li>\n"
"            <rdf:li>\n"
"               <rdf:Description>\n"
"                  <MM:SyncText ts=\"01:13.516\">all</MM:SyncText>\n"
"               </rdf:Description>\n"
"            </rdf:li>\n"
"            <rdf:li>\n"
"               <rdf:Description>\n"
"                  <MM:SyncText ts=\"01:41.744\">clear.</MM:SyncText>\n"
"               </rdf:Description>\n"
"            </rdf:li>\n"
"         </rdf:Seq>\n"
"       </rdf:Description>\n"
"    </MM:SyncEvents>\n";

Queries queries[] =
{
    { "GetCDInfoFromCDIndexId", MB_GetCDInfoFromCDIndexID,
      1, "CD Index ID", "", "", "" },
    { "FindArtist",             MB_FindArtistByName,
      1, "Artist Name", "", "", "" },
    { "FindTrack",              MB_FindTrackByName,
      3, "Track Name", "Album Name", "Artist Name", "" },
    { "FindAlbumsByArtist",     MB_FindAlbumsByArtistName,
      1, "Artist Name", "", "", "" },
    { "FindAlbum",              MB_FindAlbumByName,
      1, "Album Name", "", "", "" },
    { "FindDistinctGUID",       MB_FindDistinctGUID,
      2, "Track Name", "Artist Name", "", "" },
    { "GetArtist",              MB_GetArtistById ,
      1, "Artist ID", "", "", "" },
    { "GetAlbum",               MB_GetAlbumById ,
      1, "Album ID", "", "", "" },
    { "GetAlbumsByArtist",      MB_GetAlbumsByArtistId ,
      1, "Artist ID", "", "", "" },
    { "GetTrack",               MB_GetTrackById ,
      1, "Track ID", "", "", "" },
    { "GetTrackGUID",           MB_GetTrackByGUID ,
      1, "Track GUID", "", "", "" },
    { "GetSyncText",            MB_GetSyncTextById ,
      1, "Track ID", "", "", "" },
    { "GetCDInfo",              MB_GetCDInfo ,
      0, "", "", "", "" },
    { "GetCDTOC",               MB_GetCDTOC ,
      0, "", "", "", "" },
    { "AssociateCD",            MB_AssociateCD ,
      0, "", "", "", "" },
    { "\0",                     "\0", 0, "", "", "", "" }
};

#ifdef WIN32
#define strcasecmp stricmp
#endif

int main(void)
{
    MusicBrainz    o;
    string         error, data;
    bool           ret;
    Queries        *p;
    char           szLine[256], *szCmd, *ptr, szLast[100];
    string         xml, qarg, query, server;
    vector<string> args;

    // Set the server you want to use. Defaults to www.musicbrainz.org:80
    //server = string("www.musicbrainz.org");
    o.SetServer(server, 80);

    // Tell the client library to return data in ISO8859-1 and not UTF-8
    o.UseUTF8(0);

    // If you need to use a proxy, uncomment/edit the following line
    // as appropriate
    //o.SetProxy("proxy.mydomain.com", 80);

    for(;;)
    {
        query = "";
        printf("query> ");
        fflush(stdout);

        if (fgets(szLine, 255, stdin) < 0)
           break;

        if (strncmp(szLine, "!!", 2) == 0)
        {
            printf("%s\n", szLast);
            strcpy(szLine, szLast);
        }
        else
            strcpy(szLast, szLine);

        szLine[strlen(szLine) - 1] = 0;
        szCmd = strtok(szLine, " ");

        if (szCmd == NULL)
           continue;

        args.clear();
        for(;;)
        {
            ptr = strtok(NULL, " ");
            if (!ptr)
               break;

            if (*ptr == '\"' &&  !(*(ptr + strlen(ptr) - 1) == '\"'))
            {
               qarg = string(ptr + 1);
               for(;;)
               {
                   ptr = strtok(NULL, " ");
                   if (!ptr)
                      break;

                   if (*(ptr + strlen(ptr) - 1) == '\"')
                   {
                       *(ptr + strlen(ptr) - 1) = 0;
                       qarg += string(" ") + string(ptr);
                       ptr = (char *)qarg.c_str();
                       break;
                   }
                   qarg += string(" ") + string(ptr);
               }
               if (!ptr)
               {
                   continue;
               }
            }

            if (*ptr == '\"' &&  *(ptr + strlen(ptr) - 1) == '\"')
            {
               *(ptr + strlen(ptr) - 1) = 0;
               args.push_back(string(ptr + 1));
            }
            else
            {
               if (strcmp(ptr, "\"\"") == 0)
                  *ptr = 0;

               args.push_back(string(ptr));
            }
        }

        if (strncmp(szCmd, "bye", 3) == 0 ||
            strncmp(szCmd, "quit", 4) == 0 ||
            strncmp(szCmd, "exit", 4) == 0)
        {
            break;
        }

        if (strncmp(szCmd, "help", 4) == 0)
        {
            printf("Available commands:                Arguments:\n\n");
            for(p = queries; *p->name; p++)
            {
                printf("%-34s ", p->name);
                if (strlen(p->arg1))
                   printf("<%s> ", p->arg1);
                if (strlen(p->arg2))
                   printf("<%s> ", p->arg2);
                if (strlen(p->arg3))
                   printf("<%s> ", p->arg3);
                if (strlen(p->arg4))
                   printf("<%s> ", p->arg4);

                printf("\n");
            }
            printf("exit/quit/bye                      [quit]\n");
            printf("submit                             [get web submit URL]\n");
            printf("info                               [help on a command]\n");
            continue;
        }

        if (strncmp(szCmd, "lyrics", 6) == 0)
        {
            query = string(SUBMIT_LYRICS_QUERY);
        }

        if (strncmp(szCmd, "submit", 6) == 0)
        {
            string url;

            ret = o.GetWebSubmitURL(url);
            if (ret)
               printf("URL: %s\n", url.c_str());
            else
               printf("Could not determine web submit url.\n");

            continue;
        }

        if (strncmp(szCmd, "info", 4) == 0)
        {
            for(p = queries; p->name; p++)
            {
                if (strcasecmp(szCmd + 5, p->name) == 0)
                {
                   printf("usage: %s ", p->name);
                   if (strlen(p->arg1))
                      printf("<%s> ", p->arg1);
                   if (strlen(p->arg2))
                      printf("<%s> ", p->arg2);
                   if (strlen(p->arg3))
                      printf("<%s> ", p->arg3);
                   if (strlen(p->arg4))
                      printf("<%s> ", p->arg4);

                   printf("\n");
                   break;
                }
            }
            if (p->name == NULL)
               printf("No info available for %s\n", szCmd + 5);
            continue;
        }

        if (query.length() == 0)
        {
           for(p = queries; p->name; p++)
           {
               if (strcasecmp(szCmd, p->name) == 0)
                  break;
           }
           if (p->name == NULL)
           {
               printf("Unknown query.\n");
               continue;
           }
           query = string(p->value);
        }

        ret = o.Query(query, &args);
        if (!ret)
        {
             o.GetQueryError(error);
             printf("Query failed: %s\n", error.c_str());
             continue;
        }
        printf("Query ok. Items returned: %d\n", o.GetNumItems());

        o.GetResultRDF(xml);
        printf("Returned RDF object:\n\n%s\n", xml.c_str());
    }

    return 0;
}
<|endoftext|>


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

void
fill_storage_array_with_sentinels(gl_constant_value *storage,
				  unsigned data_size,
				  unsigned red_zone_size)
{
   for (unsigned i = 0; i < data_size; i++)
      storage[i].u = 0xDEADBEEF;

   for (unsigned i = 0; i < red_zone_size; i++)
      storage[data_size + i].u = 0xBADDC0DE;
}

/**
 * Verfiy that markers past the end of the real uniform are unmodified
 */
static ::testing::AssertionResult
red_zone_is_intact(gl_constant_value *storage,
		   unsigned data_size,
		   unsigned red_zone_size)
{
   for (unsigned i = 0; i < red_zone_size; i++) {
      const unsigned idx = data_size + i;

      if (storage[idx].u != 0xBADDC0DE)
	 return ::testing::AssertionFailure()
	    << "storage[" << idx << "].u = "  << storage[idx].u
	    << ", exepected data values = " << data_size
	    << ", red-zone size = " << red_zone_size;
   }

   return ::testing::AssertionSuccess();
}

static const int values[] = {
   2, 0, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53
};

/**
 * Generate a single data element.
 *
 * This is by both \c generate_data and \c generate_array_data to create the
 * data.
 */
static void
generate_data_element(void *mem_ctx, const glsl_type *type,
		      ir_constant *&val, unsigned data_index_base)
{
   /* Set the initial data values for the generated constant.
    */
   ir_constant_data data;
   memset(&data, 0, sizeof(data));
   for (unsigned i = 0; i < type->components(); i++) {
      const unsigned idx = (i + data_index_base) % Elements(values);
      switch (type->base_type) {
      case GLSL_TYPE_UINT:
      case GLSL_TYPE_INT:
      case GLSL_TYPE_SAMPLER:
	 data.i[i] = values[idx];
	 break;
      case GLSL_TYPE_FLOAT:
	 data.f[i] = float(values[idx]);
	 break;
      case GLSL_TYPE_BOOL:
	 data.b[i] = bool(values[idx]);
	 break;
      case GLSL_TYPE_ATOMIC_UINT:
      case GLSL_TYPE_STRUCT:
      case GLSL_TYPE_ARRAY:
      case GLSL_TYPE_VOID:
      case GLSL_TYPE_ERROR:
      case GLSL_TYPE_INTERFACE:
	 ASSERT_TRUE(false);
	 break;
      }
   }

   /* Generate and verify the constant.
    */
   val = new(mem_ctx) ir_constant(type, &data);

   for (unsigned i = 0; i < type->components(); i++) {
      switch (type->base_type) {
      case GLSL_TYPE_UINT:
      case GLSL_TYPE_INT:
      case GLSL_TYPE_SAMPLER:
	 ASSERT_EQ(data.i[i], val->value.i[i]);
	 break;
      case GLSL_TYPE_FLOAT:
	 ASSERT_EQ(data.f[i], val->value.f[i]);
	 break;
      case GLSL_TYPE_BOOL:
	 ASSERT_EQ(data.b[i], val->value.b[i]);
	 break;
      case GLSL_TYPE_ATOMIC_UINT:
      case GLSL_TYPE_STRUCT:
      case GLSL_TYPE_ARRAY:
      case GLSL_TYPE_VOID:
      case GLSL_TYPE_ERROR:
      case GLSL_TYPE_INTERFACE:
	 ASSERT_TRUE(false);
	 break;
      }
   }
}

void
generate_data(void *mem_ctx, enum glsl_base_type base_type,
	      unsigned columns, unsigned rows,
	      ir_constant *&val)
{
   /* Determine what the type of the generated constant should be.
    */
   const glsl_type *const type =
      glsl_type::get_instance(base_type, rows, columns);
   ASSERT_FALSE(type->is_error());

   generate_data_element(mem_ctx, type, val, 0);
}

void
generate_array_data(void *mem_ctx, enum glsl_base_type base_type,
		    unsigned columns, unsigned rows, unsigned array_size,
		    ir_constant *&val)
{
   /* Determine what the type of the generated constant should be.
    */
   const glsl_type *const element_type =
      glsl_type::get_instance(base_type, rows, columns);
   ASSERT_FALSE(element_type->is_error());

   const glsl_type *const array_type =
      glsl_type::get_array_instance(element_type, array_size);
   ASSERT_FALSE(array_type->is_error());

   /* Set the initial data values for the generated constant.
    */
   exec_list values_for_array;
   for (unsigned i = 0; i < array_size; i++) {
      ir_constant *element;

      generate_data_element(mem_ctx, element_type, element, i);
      values_for_array.push_tail(element);
   }

   val = new(mem_ctx) ir_constant(array_type, &values_for_array);
}

/**
 * Verify that the data stored for the uniform matches the initializer
 *
 * \param storage              Backing storage for the uniform
 * \param storage_array_size  Array size of the backing storage.  This must be
 *                            less than or equal to the array size of the type
 *                            of \c val.  If \c val is not an array, this must
 *                            be zero.
 * \param val                 Value of the initializer for the unifrom.
 * \param red_zone
 */
void
verify_data(gl_constant_value *storage, unsigned storage_array_size,
            ir_constant *val, unsigned red_zone_size,
            unsigned int boolean_true)
{
   if (val->type->base_type == GLSL_TYPE_ARRAY) {
      const glsl_type *const element_type = val->array_elements[0]->type;

      for (unsigned i = 0; i < storage_array_size; i++) {
	 verify_data(storage + (i * element_type->components()), 0,
		     val->array_elements[i], 0, boolean_true);
      }

      const unsigned components = element_type->components();

      if (red_zone_size > 0) {
	 EXPECT_TRUE(red_zone_is_intact(storage,
					storage_array_size * components,
					red_zone_size));
      }
   } else {
      ASSERT_EQ(0u, storage_array_size);
      for (unsigned i = 0; i < val->type->components(); i++) {
	 switch (val->type->base_type) {
	 case GLSL_TYPE_UINT:
	 case GLSL_TYPE_INT:
	 case GLSL_TYPE_SAMPLER:
	    EXPECT_EQ(val->value.i[i], storage[i].i);
	    break;
	 case GLSL_TYPE_FLOAT:
	    EXPECT_EQ(val->value.f[i], storage[i].f);
	    break;
	 case GLSL_TYPE_BOOL:
	    EXPECT_EQ(val->value.b[i] ? boolean_true : 0, storage[i].i);
	    break;
         case GLSL_TYPE_ATOMIC_UINT:
	 case GLSL_TYPE_STRUCT:
	 case GLSL_TYPE_ARRAY:
	 case GLSL_TYPE_VOID:
	 case GLSL_TYPE_ERROR:
	 case GLSL_TYPE_INTERFACE:
	    ASSERT_TRUE(false);
	    break;
	 }
      }

      if (red_zone_size > 0) {
	 EXPECT_TRUE(red_zone_is_intact(storage,
					val->type->components(),
					red_zone_size));
      }
   }
}
<commit_msg>glsl/tests: add IMAGE type.<commit_after>/*
 * Copyright © 2012 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
#include <gtest/gtest.h>
#include "main/mtypes.h"
#include "main/macros.h"
#include "util/ralloc.h"
#include "uniform_initializer_utils.h"
#include <stdio.h>

void
fill_storage_array_with_sentinels(gl_constant_value *storage,
				  unsigned data_size,
				  unsigned red_zone_size)
{
   for (unsigned i = 0; i < data_size; i++)
      storage[i].u = 0xDEADBEEF;

   for (unsigned i = 0; i < red_zone_size; i++)
      storage[data_size + i].u = 0xBADDC0DE;
}

/**
 * Verfiy that markers past the end of the real uniform are unmodified
 */
static ::testing::AssertionResult
red_zone_is_intact(gl_constant_value *storage,
		   unsigned data_size,
		   unsigned red_zone_size)
{
   for (unsigned i = 0; i < red_zone_size; i++) {
      const unsigned idx = data_size + i;

      if (storage[idx].u != 0xBADDC0DE)
	 return ::testing::AssertionFailure()
	    << "storage[" << idx << "].u = "  << storage[idx].u
	    << ", exepected data values = " << data_size
	    << ", red-zone size = " << red_zone_size;
   }

   return ::testing::AssertionSuccess();
}

static const int values[] = {
   2, 0, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53
};

/**
 * Generate a single data element.
 *
 * This is by both \c generate_data and \c generate_array_data to create the
 * data.
 */
static void
generate_data_element(void *mem_ctx, const glsl_type *type,
		      ir_constant *&val, unsigned data_index_base)
{
   /* Set the initial data values for the generated constant.
    */
   ir_constant_data data;
   memset(&data, 0, sizeof(data));
   for (unsigned i = 0; i < type->components(); i++) {
      const unsigned idx = (i + data_index_base) % Elements(values);
      switch (type->base_type) {
      case GLSL_TYPE_UINT:
      case GLSL_TYPE_INT:
      case GLSL_TYPE_SAMPLER:
      case GLSL_TYPE_IMAGE:
	 data.i[i] = values[idx];
	 break;
      case GLSL_TYPE_FLOAT:
	 data.f[i] = float(values[idx]);
	 break;
      case GLSL_TYPE_BOOL:
	 data.b[i] = bool(values[idx]);
	 break;
      case GLSL_TYPE_ATOMIC_UINT:
      case GLSL_TYPE_STRUCT:
      case GLSL_TYPE_ARRAY:
      case GLSL_TYPE_VOID:
      case GLSL_TYPE_ERROR:
      case GLSL_TYPE_INTERFACE:
	 ASSERT_TRUE(false);
	 break;
      }
   }

   /* Generate and verify the constant.
    */
   val = new(mem_ctx) ir_constant(type, &data);

   for (unsigned i = 0; i < type->components(); i++) {
      switch (type->base_type) {
      case GLSL_TYPE_UINT:
      case GLSL_TYPE_INT:
      case GLSL_TYPE_SAMPLER:
      case GLSL_TYPE_IMAGE:
	 ASSERT_EQ(data.i[i], val->value.i[i]);
	 break;
      case GLSL_TYPE_FLOAT:
	 ASSERT_EQ(data.f[i], val->value.f[i]);
	 break;
      case GLSL_TYPE_BOOL:
	 ASSERT_EQ(data.b[i], val->value.b[i]);
	 break;
      case GLSL_TYPE_ATOMIC_UINT:
      case GLSL_TYPE_STRUCT:
      case GLSL_TYPE_ARRAY:
      case GLSL_TYPE_VOID:
      case GLSL_TYPE_ERROR:
      case GLSL_TYPE_INTERFACE:
	 ASSERT_TRUE(false);
	 break;
      }
   }
}

void
generate_data(void *mem_ctx, enum glsl_base_type base_type,
	      unsigned columns, unsigned rows,
	      ir_constant *&val)
{
   /* Determine what the type of the generated constant should be.
    */
   const glsl_type *const type =
      glsl_type::get_instance(base_type, rows, columns);
   ASSERT_FALSE(type->is_error());

   generate_data_element(mem_ctx, type, val, 0);
}

void
generate_array_data(void *mem_ctx, enum glsl_base_type base_type,
		    unsigned columns, unsigned rows, unsigned array_size,
		    ir_constant *&val)
{
   /* Determine what the type of the generated constant should be.
    */
   const glsl_type *const element_type =
      glsl_type::get_instance(base_type, rows, columns);
   ASSERT_FALSE(element_type->is_error());

   const glsl_type *const array_type =
      glsl_type::get_array_instance(element_type, array_size);
   ASSERT_FALSE(array_type->is_error());

   /* Set the initial data values for the generated constant.
    */
   exec_list values_for_array;
   for (unsigned i = 0; i < array_size; i++) {
      ir_constant *element;

      generate_data_element(mem_ctx, element_type, element, i);
      values_for_array.push_tail(element);
   }

   val = new(mem_ctx) ir_constant(array_type, &values_for_array);
}

/**
 * Verify that the data stored for the uniform matches the initializer
 *
 * \param storage              Backing storage for the uniform
 * \param storage_array_size  Array size of the backing storage.  This must be
 *                            less than or equal to the array size of the type
 *                            of \c val.  If \c val is not an array, this must
 *                            be zero.
 * \param val                 Value of the initializer for the unifrom.
 * \param red_zone
 */
void
verify_data(gl_constant_value *storage, unsigned storage_array_size,
            ir_constant *val, unsigned red_zone_size,
            unsigned int boolean_true)
{
   if (val->type->base_type == GLSL_TYPE_ARRAY) {
      const glsl_type *const element_type = val->array_elements[0]->type;

      for (unsigned i = 0; i < storage_array_size; i++) {
	 verify_data(storage + (i * element_type->components()), 0,
		     val->array_elements[i], 0, boolean_true);
      }

      const unsigned components = element_type->components();

      if (red_zone_size > 0) {
	 EXPECT_TRUE(red_zone_is_intact(storage,
					storage_array_size * components,
					red_zone_size));
      }
   } else {
      ASSERT_EQ(0u, storage_array_size);
      for (unsigned i = 0; i < val->type->components(); i++) {
	 switch (val->type->base_type) {
	 case GLSL_TYPE_UINT:
	 case GLSL_TYPE_INT:
	 case GLSL_TYPE_SAMPLER:
	 case GLSL_TYPE_IMAGE:
	    EXPECT_EQ(val->value.i[i], storage[i].i);
	    break;
	 case GLSL_TYPE_FLOAT:
	    EXPECT_EQ(val->value.f[i], storage[i].f);
	    break;
	 case GLSL_TYPE_BOOL:
	    EXPECT_EQ(val->value.b[i] ? boolean_true : 0, storage[i].i);
	    break;
         case GLSL_TYPE_ATOMIC_UINT:
	 case GLSL_TYPE_STRUCT:
	 case GLSL_TYPE_ARRAY:
	 case GLSL_TYPE_VOID:
	 case GLSL_TYPE_ERROR:
	 case GLSL_TYPE_INTERFACE:
	    ASSERT_TRUE(false);
	    break;
	 }
      }

      if (red_zone_size > 0) {
	 EXPECT_TRUE(red_zone_is_intact(storage,
					val->type->components(),
					red_zone_size));
      }
   }
}
<|endoftext|>