<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2005-2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

*/

#include "videowidget.h"
#include "videowidget_p.h"
#include "videowidgetinterface.h"
#include "factory.h"
#include "phonondefs_p.h"
#include "phononnamespace_p.h"

#include <QtGui/QAction>

#define PHONON_INTERFACENAME VideoWidgetInterface

namespace Phonon
{

VideoWidget::VideoWidget(QWidget *parent)
    : QWidget(parent)
    , Phonon::AbstractVideoOutput(*new VideoWidgetPrivate(this))
{
    K_D(VideoWidget);
    d->init();
    d->createBackendObject();
    setMouseTracking(true);
}

VideoWidget::VideoWidget(VideoWidgetPrivate &dd, QWidget *parent)
    : QWidget(parent),
    Phonon::AbstractVideoOutput(dd)
{
    K_D(VideoWidget);
    d->init();
}

void VideoWidgetPrivate::init()
{
    Q_Q(VideoWidget);
    QObject::connect(&cursorTimer, SIGNAL(timeout()), q, SLOT(_k_cursorTimeout()));
    cursorTimer.start();
}

void VideoWidget::mouseMoveEvent(QMouseEvent *)
{
    K_D(VideoWidget);
    if (k_ptr->backendObject()) {
        QWidget *w = INTERFACE_CALL(widget());
        if (w && Qt::BlankCursor == w->cursor().shape()) {
            unsetCursor();
            d->cursorTimer.start();
        }
    }
}

void VideoWidgetPrivate::_k_cursorTimeout()
{
    if (m_backendObject) {
        QWidget *w = pINTERFACE_CALL(widget());
        if (w && Qt::ArrowCursor == w->cursor().shape()) {
            q_func()->setCursor(Qt::BlankCursor);
        }
    }
}
void VideoWidgetPrivate::createBackendObject()
{
    if (m_backendObject)
        return;
    Q_Q(VideoWidget);
    m_backendObject = Factory::createVideoWidget(q);
    if (m_backendObject) {
        setupBackendObject();
    }
}

#define PHONON_CLASSNAME VideoWidget

PHONON_INTERFACE_GETTER(Phonon::VideoWidget::AspectRatio, aspectRatio, d->aspectRatio)
PHONON_INTERFACE_SETTER(setAspectRatio, aspectRatio, Phonon::VideoWidget::AspectRatio)

PHONON_INTERFACE_GETTER(Phonon::VideoWidget::ScaleMode, scaleMode, d->scaleMode)
PHONON_INTERFACE_SETTER(setScaleMode, scaleMode, Phonon::VideoWidget::ScaleMode)

PHONON_INTERFACE_GETTER(qreal, brightness, d->brightness)
PHONON_INTERFACE_SETTER(setBrightness, brightness, qreal)

PHONON_INTERFACE_GETTER(qreal, contrast, d->contrast)
PHONON_INTERFACE_SETTER(setContrast, contrast, qreal)

PHONON_INTERFACE_GETTER(qreal, hue, d->hue)
PHONON_INTERFACE_SETTER(setHue, hue, qreal)

PHONON_INTERFACE_GETTER(qreal, saturation, d->saturation)
PHONON_INTERFACE_SETTER(setSaturation, saturation, qreal)

void VideoWidget::setFullScreen(bool newFullScreen)
{
    pDebug() << Q_FUNC_INFO << newFullScreen;
    K_D(VideoWidget);
    // TODO: disable screensaver? or should we leave that responsibility to the
    // application?
    Qt::WindowFlags flags = windowFlags();
    if (newFullScreen) {
        d->changeFlags = !(flags & Qt::Window);
        if (d->changeFlags) {
            flags &= ~Qt::SubWindow;
            flags |= Qt::Window;
        } // else it's a toplevel window already
    } else if (d->changeFlags && parent()) {
        flags &= ~Qt::Window;
        flags |= Qt::SubWindow;
    }
    setWindowFlags(flags);
    if (newFullScreen) {
        showFullScreen();
    } else {
        showNormal();
    }
}

void VideoWidget::exitFullScreen()
{
    setFullScreen(false);
}

void VideoWidget::enterFullScreen()
{
    setFullScreen(true);
}

bool VideoWidgetPrivate::aboutToDeleteBackendObject()
{
    aspectRatio = pINTERFACE_CALL(aspectRatio());
    scaleMode = pINTERFACE_CALL(scaleMode());
    return AbstractVideoOutputPrivate::aboutToDeleteBackendObject();
}

void VideoWidgetPrivate::setupBackendObject()
{
    Q_Q(VideoWidget);
    Q_ASSERT(m_backendObject);
    //AbstractVideoOutputPrivate::setupBackendObject();
    pDebug() << "calling setAspectRatio on the backend " << aspectRatio;
    pINTERFACE_CALL(setAspectRatio(aspectRatio));
    pINTERFACE_CALL(setScaleMode(scaleMode));

    QWidget *w = pINTERFACE_CALL(widget());
    if (w) {
        layout.addWidget(w);
        q->setSizePolicy(w->sizePolicy());
        w->setMouseTracking(true);
    }
}

/*
QSize VideoWidget::sizeHint()
{
    if (k_ptr->backendObject())
    {
        QWidget *w = pINTERFACE_CALL(widget());
        if (w)
            return w->sizeHint();
    }
    return QSize(0, 0);
}

QSize VideoWidget::minimumSizeHint()
{
    if (k_ptr->backendObject())
    {
        QWidget *w = pINTERFACE_CALL(widget());
        if (w)
            return w->minimumSizeHint();
    }
    return QSize(0, 0);
} */

} //namespace Phonon

#include "moc_videowidget.cpp"

#undef PHONON_CLASSNAME
// vim: sw=4 ts=4 tw=80
<commit_msg>complementary update (removing useless code)<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2005-2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

*/

#include "videowidget.h"
#include "videowidget_p.h"
#include "videowidgetinterface.h"
#include "factory.h"
#include "phonondefs_p.h"
#include "phononnamespace_p.h"

#include <QtGui/QAction>

#define PHONON_INTERFACENAME VideoWidgetInterface

namespace Phonon
{

VideoWidget::VideoWidget(QWidget *parent)
    : QWidget(parent)
    , Phonon::AbstractVideoOutput(*new VideoWidgetPrivate(this))
{
    K_D(VideoWidget);
    d->init();
    d->createBackendObject();
    setMouseTracking(true);
}

VideoWidget::VideoWidget(VideoWidgetPrivate &dd, QWidget *parent)
    : QWidget(parent),
    Phonon::AbstractVideoOutput(dd)
{
    K_D(VideoWidget);
    d->init();
}

void VideoWidgetPrivate::init()
{
    Q_Q(VideoWidget);
    QObject::connect(&cursorTimer, SIGNAL(timeout()), q, SLOT(_k_cursorTimeout()));
    cursorTimer.start();
}

void VideoWidget::mouseMoveEvent(QMouseEvent *)
{
    K_D(VideoWidget);
    if (Qt::BlankCursor == cursor().shape()) {
        unsetCursor();
        d->cursorTimer.start();
    }
}

void VideoWidgetPrivate::_k_cursorTimeout()
{
    Q_Q(VideoWidget);
    if (Qt::ArrowCursor == q->cursor().shape()) {
        q->setCursor(Qt::BlankCursor);
    }
}

void VideoWidgetPrivate::createBackendObject()
{
    if (m_backendObject)
        return;
    Q_Q(VideoWidget);
    m_backendObject = Factory::createVideoWidget(q);
    if (m_backendObject) {
        setupBackendObject();
    }
}

#define PHONON_CLASSNAME VideoWidget

PHONON_INTERFACE_GETTER(Phonon::VideoWidget::AspectRatio, aspectRatio, d->aspectRatio)
PHONON_INTERFACE_SETTER(setAspectRatio, aspectRatio, Phonon::VideoWidget::AspectRatio)

PHONON_INTERFACE_GETTER(Phonon::VideoWidget::ScaleMode, scaleMode, d->scaleMode)
PHONON_INTERFACE_SETTER(setScaleMode, scaleMode, Phonon::VideoWidget::ScaleMode)

PHONON_INTERFACE_GETTER(qreal, brightness, d->brightness)
PHONON_INTERFACE_SETTER(setBrightness, brightness, qreal)

PHONON_INTERFACE_GETTER(qreal, contrast, d->contrast)
PHONON_INTERFACE_SETTER(setContrast, contrast, qreal)

PHONON_INTERFACE_GETTER(qreal, hue, d->hue)
PHONON_INTERFACE_SETTER(setHue, hue, qreal)

PHONON_INTERFACE_GETTER(qreal, saturation, d->saturation)
PHONON_INTERFACE_SETTER(setSaturation, saturation, qreal)

void VideoWidget::setFullScreen(bool newFullScreen)
{
    pDebug() << Q_FUNC_INFO << newFullScreen;
    K_D(VideoWidget);
    // TODO: disable screensaver? or should we leave that responsibility to the
    // application?
    Qt::WindowFlags flags = windowFlags();
    if (newFullScreen) {
        d->changeFlags = !(flags & Qt::Window);
        if (d->changeFlags) {
            flags &= ~Qt::SubWindow;
            flags |= Qt::Window;
        } // else it's a toplevel window already
    } else if (d->changeFlags && parent()) {
        flags &= ~Qt::Window;
        flags |= Qt::SubWindow;
    }
    setWindowFlags(flags);
    if (newFullScreen) {
        showFullScreen();
    } else {
        showNormal();
    }
}

void VideoWidget::exitFullScreen()
{
    setFullScreen(false);
}

void VideoWidget::enterFullScreen()
{
    setFullScreen(true);
}

bool VideoWidgetPrivate::aboutToDeleteBackendObject()
{
    aspectRatio = pINTERFACE_CALL(aspectRatio());
    scaleMode = pINTERFACE_CALL(scaleMode());
    return AbstractVideoOutputPrivate::aboutToDeleteBackendObject();
}

void VideoWidgetPrivate::setupBackendObject()
{
    Q_Q(VideoWidget);
    Q_ASSERT(m_backendObject);
    //AbstractVideoOutputPrivate::setupBackendObject();
    pDebug() << "calling setAspectRatio on the backend " << aspectRatio;
    pINTERFACE_CALL(setAspectRatio(aspectRatio));
    pINTERFACE_CALL(setScaleMode(scaleMode));

    QWidget *w = pINTERFACE_CALL(widget());
    if (w) {
        layout.addWidget(w);
        q->setSizePolicy(w->sizePolicy());
        w->setMouseTracking(true);
    }
}

/*
QSize VideoWidget::sizeHint()
{
    if (k_ptr->backendObject())
    {
        QWidget *w = pINTERFACE_CALL(widget());
        if (w)
            return w->sizeHint();
    }
    return QSize(0, 0);
}

QSize VideoWidget::minimumSizeHint()
{
    if (k_ptr->backendObject())
    {
        QWidget *w = pINTERFACE_CALL(widget());
        if (w)
            return w->minimumSizeHint();
    }
    return QSize(0, 0);
} */

} //namespace Phonon

#include "moc_videowidget.cpp"

#undef PHONON_CLASSNAME
// vim: sw=4 ts=4 tw=80
<|endoftext|>


<commit_before>#include <stdio.h>
#include <signal.h>
#include <fstream>
#include <unistd.h>
#include <cmath>

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <turtlesim/Pose.h>

#include "json/json.h"

#define LOCATION_EPSILON 0.01
#define ANGLE_EPSILON 0.005

void quit(int sig) {
  ROS_INFO("quit");
  ros::shutdown();
  exit(0);
}

// ---------------------------------------------------------

class Vector2D {
  /** a simple, 2d point class */

public:
    float x, y;

    Vector2D(double _x, double _y) : x(_x), y(_y) {}

    /** vector substraction */
    Vector2D operator-(const Vector2D& other) {
      Vector2D rtv(x - other.x, y - other.y);
      return rtv;
    }

    /** vector addition */
    Vector2D operator+(const Vector2D& other) {
      Vector2D rtv(x + other.x, y * other.y);
      return rtv;
    }

    /** length of this vector, L_2 norm */
    double length() {
      return sqrt(x * x + y * y);
    }

    /** the angle of the vector */
    double angle() {
      return atan2(y, x);
    }
};

// ---------------------------------------------------------

/** simple class that simply translates instructions from json into message for
    the turtle1/cmd_vel topic */
class TurtleDraw {
public:

  /** @param instructions is a JSON array of objects, each of which
      can contain linear and/or angular_deg fields, specifying linear and
      angular velocity
  */
  TurtleDraw(Json::Value instructions);

  /** loop just loops through the instructions and send them to the turtle (via
      the cmd_vel topic) */
  // void loop();

private:

  ros::NodeHandle nh_;
  ros::Publisher twist_pub_;
  ros::Subscriber pose_sub_;
  Json::Value instructions_;

  Vector2D currentLocation;
  double currentAngle;

  Vector2D nextGoal;
  int navIndex;

  void turtlePoseCB(const turtlesim::Pose::ConstPtr& msg);

  void getNextGoal() {
    nextGoal.x = instructions_[navIndex][0].asDouble();
    nextGoal.y = instructions_[navIndex][1].asDouble();
    ++navIndex;
  }

  bool done() {
    return (navIndex >= instructions_.size());
  }
};

// ---------------------------------------------------------

TurtleDraw::TurtleDraw(Json::Value instructions):
  instructions_(instructions),
  currentLocation(0,0),
  nextGoal(0,0),
  navIndex(0)
{
  twist_pub_ = nh_.advertise<geometry_msgs::Twist>("turtle1/cmd_vel", 1);
  pose_sub_ = nh_.subscribe("/turtle1/pose", 1, &TurtleDraw::turtlePoseCB, this);
  getNextGoal();
}

void TurtleDraw::turtlePoseCB(const turtlesim::Pose::ConstPtr& msg) {
  ROS_INFO_STREAM("new pose, theta:" << msg->theta);
  currentLocation.x = msg->x;
  currentLocation.y = msg->y;
  currentAngle = msg->theta;

  geometry_msgs::Twist twist;
  Vector2D delta = nextGoal - currentLocation;

  ROS_INFO_STREAM(
    "heading: " << currentAngle
    << ", direction to goal: " << delta.angle()
    << ", delta length: " << delta.length()
  );

  if (delta.length() < LOCATION_EPSILON) {
    // we've arrived at the next nav point

    if (done()) {
      // this was the last navigation point, we are done!
      quit(0);
    }

    getNextGoal();

  } else {

    twist.angular.z = delta.angle() - currentAngle;

    // if deviated too much from direction, stop and turn
    if (std::abs(delta.angle() - currentAngle) > ANGLE_EPSILON) {
      twist.linear.x = 0;
    } else {
      // otherwise, move
      twist.linear.x = delta.length();
    }

    ROS_INFO_STREAM("x: " << twist.linear.x
      << ", z: " << twist.angular.z
      << ", heading: " << currentAngle
      << ", direction to goal: " << delta.angle()
      << ", delta length: " << delta.length()
    );
    twist_pub_.publish(twist);
  }
}

// // TODO: this needs to move in with turtlePoseCB
// void TurtleDraw::loop() {
//
//   // rate at which we'll send instructions
//   ros::Rate rate(10); // hz
//   rate.sleep();
//
//   geometry_msgs::Twist twist;
//
//   // Iterate over sequence of instructions
//   for ( int i = 0; i < instructions_.size(); ++i ) {
//     ROS_DEBUG_STREAM(i << ": " << instructions_[i]);
//     Vector2D nextGoal(instructions_[i][0].asDouble(),
//       instructions_[i][1].asDouble());
//     Vector2D delta = nextGoal - currentLocation;
//
//     while (delta.length() > LOCATION_EPSILON) {
//
//       // we also turn towards the goal
//       twist.angular.z = delta.angle() - currentAngle;
//
//       // if deviated too much from direction, stop and turn
//       if (std::abs(delta.angle() - currentAngle) > ANGLE_EPSILON) {
//         twist.linear.x = 0;
//       } else {
//         // otherwise, move
//         twist.linear.x = delta.length();
//       }
//
//       ROS_INFO_STREAM("x: " << twist.linear.x
//         << ", z: " << twist.angular.z
//         << ", heading: " << currentAngle
//         << ", direction to goal: " << delta.angle()
//         << ", delta length: " << delta.length()
//       );
//       twist_pub_.publish(twist);
//
//       rate.sleep();
//       delta = nextGoal - currentLocation;
//
//     }
//
//     // we've arrived at the next nav point
//   }
//
//   // we've arrived at the last nav point
//
//   return;
// }

// ---------------------------------------------------------

int main(int argc, char** argv) {

  ros::init(argc, argv, "turtle_draw");
  signal(SIGINT,quit);
  ROS_INFO("START");

  ROS_INFO("loading shape from file %s", argv[1]);
  /* these files are just arrays of instruction with each instruction specifying
     a linear and/or angular_deg velocity, where the latter is just like angular
     but in degree rather than radian, which is easier for humans when
     specifying stars */
  std::ifstream file_in(argv[1]);
  Json::Value instructions = Json::Value();
  file_in >> instructions;

  // let's go
  TurtleDraw turtleDraw(instructions);
  ros::spin();

  return(0);
}
<commit_msg>Added a speed multiple parameter<commit_after>#include <stdio.h>
#include <signal.h>
#include <fstream>
#include <unistd.h>
#include <cmath>

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <turtlesim/Pose.h>

#include "json/json.h"

#define LOCATION_EPSILON 0.01
#define ANGLE_EPSILON 0.005
#define SPEED 3.0

void quit(int sig) {
  ROS_INFO("quit");
  ros::shutdown();
  exit(0);
}

// ---------------------------------------------------------

class Vector2D {
  /** a simple, 2d point class */

public:
    float x, y;

    Vector2D(double _x, double _y) : x(_x), y(_y) {}

    /** vector substraction */
    Vector2D operator-(const Vector2D& other) {
      Vector2D rtv(x - other.x, y - other.y);
      return rtv;
    }

    /** vector addition */
    Vector2D operator+(const Vector2D& other) {
      Vector2D rtv(x + other.x, y * other.y);
      return rtv;
    }

    /** length of this vector, L_2 norm */
    double length() {
      return sqrt(x * x + y * y);
    }

    /** the angle of the vector */
    double angle() {
      return atan2(y, x);
    }
};

// ---------------------------------------------------------

/** simple class that simply translates instructions from json into message for
    the turtle1/cmd_vel topic */
class TurtleDraw {
public:

  /** @param instructions is a JSON array of objects, each of which
      can contain linear and/or angular_deg fields, specifying linear and
      angular velocity
  */
  TurtleDraw(Json::Value instructions);

  /** loop just loops through the instructions and send them to the turtle (via
      the cmd_vel topic) */
  // void loop();

private:

  ros::NodeHandle nh_;
  ros::Publisher twist_pub_;
  ros::Subscriber pose_sub_;
  Json::Value instructions_;

  Vector2D currentLocation;
  double currentAngle;

  Vector2D nextGoal;
  int navIndex;

  void turtlePoseCB(const turtlesim::Pose::ConstPtr& msg);

  void getNextGoal() {
    nextGoal.x = instructions_[navIndex][0].asDouble();
    nextGoal.y = instructions_[navIndex][1].asDouble();
    ++navIndex;
  }

  bool done() {
    return (navIndex >= instructions_.size());
  }
};

// ---------------------------------------------------------

TurtleDraw::TurtleDraw(Json::Value instructions):
  instructions_(instructions),
  currentLocation(0,0),
  nextGoal(0,0),
  navIndex(0)
{
  twist_pub_ = nh_.advertise<geometry_msgs::Twist>("turtle1/cmd_vel", 1);
  pose_sub_ = nh_.subscribe("/turtle1/pose", 1, &TurtleDraw::turtlePoseCB, this);
  getNextGoal();
}

void TurtleDraw::turtlePoseCB(const turtlesim::Pose::ConstPtr& msg) {
  ROS_INFO_STREAM("new pose, theta:" << msg->theta);
  currentLocation.x = msg->x;
  currentLocation.y = msg->y;
  currentAngle = msg->theta;

  geometry_msgs::Twist twist;
  Vector2D delta = nextGoal - currentLocation;

  ROS_INFO_STREAM(
    "heading: " << currentAngle
    << ", direction to goal: " << delta.angle()
    << ", delta length: " << delta.length()
  );

  if (delta.length() < LOCATION_EPSILON) {
    // we've arrived at the next nav point

    if (done()) {
      // this was the last navigation point, we are done!
      quit(0);
    }

    getNextGoal();

  } else {

    twist.angular.z = (delta.angle() - currentAngle) * SPEED;

    // if deviated too much from direction, stop and turn
    if (std::abs(delta.angle() - currentAngle) > ANGLE_EPSILON) {
      twist.linear.x = 0;
    } else {
      // otherwise, move
      twist.linear.x = delta.length() * SPEED;
    }

    ROS_INFO_STREAM("x: " << twist.linear.x
      << ", z: " << twist.angular.z
      << ", heading: " << currentAngle
      << ", direction to goal: " << delta.angle()
      << ", delta length: " << delta.length()
    );
    twist_pub_.publish(twist);
  }
}

// // TODO: this needs to move in with turtlePoseCB
// void TurtleDraw::loop() {
//
//   // rate at which we'll send instructions
//   ros::Rate rate(10); // hz
//   rate.sleep();
//
//   geometry_msgs::Twist twist;
//
//   // Iterate over sequence of instructions
//   for ( int i = 0; i < instructions_.size(); ++i ) {
//     ROS_DEBUG_STREAM(i << ": " << instructions_[i]);
//     Vector2D nextGoal(instructions_[i][0].asDouble(),
//       instructions_[i][1].asDouble());
//     Vector2D delta = nextGoal - currentLocation;
//
//     while (delta.length() > LOCATION_EPSILON) {
//
//       // we also turn towards the goal
//       twist.angular.z = delta.angle() - currentAngle;
//
//       // if deviated too much from direction, stop and turn
//       if (std::abs(delta.angle() - currentAngle) > ANGLE_EPSILON) {
//         twist.linear.x = 0;
//       } else {
//         // otherwise, move
//         twist.linear.x = delta.length();
//       }
//
//       ROS_INFO_STREAM("x: " << twist.linear.x
//         << ", z: " << twist.angular.z
//         << ", heading: " << currentAngle
//         << ", direction to goal: " << delta.angle()
//         << ", delta length: " << delta.length()
//       );
//       twist_pub_.publish(twist);
//
//       rate.sleep();
//       delta = nextGoal - currentLocation;
//
//     }
//
//     // we've arrived at the next nav point
//   }
//
//   // we've arrived at the last nav point
//
//   return;
// }

// ---------------------------------------------------------

int main(int argc, char** argv) {

  ros::init(argc, argv, "turtle_draw");
  signal(SIGINT,quit);
  ROS_INFO("START");

  ROS_INFO("loading shape from file %s", argv[1]);
  /* these files are just arrays of instruction with each instruction specifying
     a linear and/or angular_deg velocity, where the latter is just like angular
     but in degree rather than radian, which is easier for humans when
     specifying stars */
  std::ifstream file_in(argv[1]);
  Json::Value instructions = Json::Value();
  file_in >> instructions;

  // let's go
  TurtleDraw turtleDraw(instructions);
  ros::spin();

  return(0);
}
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkVTKImageIO.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

  Portions of this code are covered under the VTK copyright.
  See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm 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 "itkVTKImageIO.h"
#include <stdio.h>
#include "itkByteSwapper.h"

namespace itk
{

VTKImageIO::VTKImageIO()
{
  this->SetNumberOfDimensions(2);
  m_ByteOrder = LittleEndian;
  m_FileType = Binary;

}

VTKImageIO::~VTKImageIO()
{
}

bool VTKImageIO::OpenVTKFileForReading(std::ifstream& os,
                                       const char* filename)

{
  // Make sure that we have a file to
  if ( filename == "" )
    {
    itkExceptionMacro(<<"A FileName must be specified.");
    return false;
    }

  // Close file from any previous image
  if ( os.is_open() )
    {
    os.close();
    }

  // Open the new file for reading
  itkDebugMacro(<< "Initialize: opening file " << filename);

  // Actually open the file

#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
  const int openMode = std::ios::in|std::ios::binary;
#elif ( defined(__GNUC__) && __GNUC__ >= 3 ) || defined (__MWERKS__) || defined (__INTEL_COMPILER) || defined (__MINGW32__) || defined(__CYGWIN__)
  const std::ios_base::openmode openMode = std::ios::in;
#else
  const int openMode = std::ios::in;
#endif
  os.open(filename, openMode);
  if ( os.fail() )
    {
    itkExceptionMacro(<< "Could not open file for reading: " << filename);
    return false;
    }

  return true;
}

bool VTKImageIO::OpenVTKFileForWriting(std::ofstream& os,
                                       const char* filename)

{
  // Make sure that we have a file to
  if ( filename == "" )
    {
    itkExceptionMacro(<<"A FileName must be specified.");
    return false;
    }

  // Create the file. This is required on some older sgi's
  std::ofstream tFile(filename,std::ios::out);
  tFile.close();

  // Close file from any previous image
  if ( os.is_open() )
    {
    os.close();
    }

  // Open the new file for writing
  itkDebugMacro(<< "Initialize: opening file " << filename);

  // Actually open the file
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
  const int openMode = std::ios::out|std::ios::binary;
#elif (defined(__GNUC__) && __GNUC__ >= 3) || defined (__MWERKS__) || defined (__INTEL_COMPILER) || defined (__MINGW32__) || defined(__CYGWIN__)
  const std::ios_base::openmode openMode =std::ios::out;
#else
  const int openMode = std::ios::out;
#endif
  os.open(filename, openMode);
  if ( os.fail() )
    {
    itkExceptionMacro(<< "Could not open file for writing: " << filename);
    return false;
    }

  return true;
}

bool VTKImageIO::CanReadFile(const char* filename)
{
  std::ifstream file;
  char buffer[256];
  std::string fname(filename);

  if ( fname.find(".vtk") >= fname.length() )
    {
    return false;
    }

  if ( ! this->OpenVTKFileForReading(file, filename) )
    {
    return false;
    }

  // Check to see if its a vtk structured points file
  file.getline(buffer,255);
  file.getline(buffer,255);
  file.getline(buffer,255);
  file.getline(buffer,255);

  fname = buffer;

  if ( fname.find("STRUCTURED_POINTS") < fname.length() ||
       fname.find("structured_points") < fname.length() )
    {
    return true;
    }
  else
    {
    return false;
    }
}

void VTKImageIO::InternalReadImageInformation(std::ifstream& file)
{
  char line[255];
  std::string text;

  if ( ! this->OpenVTKFileForReading(file, m_FileName.c_str()) )
    {
    itkExceptionMacro(<< "Cannot read requested file");
    }

  file.getline(line,255);
  file.getline(line,255);
  file.getline(line,255);
  text = line;
  if ( text.find("ASCII") < text.length() ||
       text.find("ascii") < text.length() )
    {
    this->SetFileTypeToASCII();
    }
  else if ( text.find("BINARY") < text.length() ||
            text.find("binary") < text.length() )
    {
    this->SetFileTypeToBinary();
    }
  else
    {
    itkExceptionMacro(<< "Unrecognized type");
    }
  file.getline(line,255);
  text = line;
  if ( text.find("STRUCTURED_POINTS") >= text.length() &&
       text.find("structured_points") >= text.length() )
    {
    itkExceptionMacro(<< "Not structured points, can't read");
    }

  //extract dimensions, spacing, origin
  unsigned int dims[3];
  float spacing[3];
  float origin[3];
  file.getline(line,255);
  text = line;

  // set values in case we don't find them
  this->SetNumberOfDimensions(3);
  m_Spacing[0] = 1.0;
  m_Spacing[1] = 1.0;
  m_Spacing[2] = 1.0;
  m_Origin[0] = 0.0;
  m_Origin[1] = 0.0;
  m_Origin[2] = 0.0;

  if ( text.find("DIMENSIONS") < text.length() ||
       text.find("dimensions") < text.length() )
    {
    sscanf(line, "%*s %d %d %d", dims, dims+1, dims+2);
    if ( dims[2] <= 1 )
      {
      this->SetNumberOfDimensions(2);
      }
    else
      {
      this->SetNumberOfDimensions(3);
      }
    for ( unsigned int i=0; i < m_NumberOfDimensions; i++ )
      {
      m_Dimensions[i] = dims[i];
      }
    }
  else
    {
    itkExceptionMacro(<<"No dimensions defined");
    }

  for ( bool readScalars=false; !readScalars; )
    {
    file.getline(line,255);
    text = line;

    if ( text.find("SPACING") < text.length() ||
         text.find("spacing") < text.length() )
      {
      sscanf(line, "%*s %f %f %f", spacing, spacing+1, spacing+2);
      for ( unsigned int i=0; i < m_NumberOfDimensions; i++ )
        {
        m_Spacing[i] = spacing[i];
        }
      }

    else if ( text.find("ORIGIN") < text.length() ||
              text.find("origin") < text.length() )
      {
      sscanf(line, "%*s %f %f %f", origin, origin+1, origin+2);
      for ( unsigned int i=0; i < m_NumberOfDimensions; i++ )
        {
        m_Origin[i] = origin[i];
        }
      }

    else if ( text.find("COLOR_SCALARS") < text.length() ||
              text.find("color_scalars") < text.length() )
      {
      readScalars = true;

      int numComp = 1;
      sscanf(line, "%*s %*s %d", &numComp);
      if (numComp == 1)
        {
        SetPixelType(SCALAR);
        }
      else
        {
        SetPixelType(VECTOR);
        }
      if ( this->GetFileType() == ASCII )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(FLOAT);
        }
      else
        {
        SetNumberOfComponents(numComp);
        SetComponentType(UCHAR);
        }
      }

    else if ( text.find("SCALARS") < text.length() ||
              text.find("scalars") < text.length() )
      {
      readScalars = true;

      char pixelType[256];
      int numComp = 1;
      sscanf(line, "%*s %*s %s %d", pixelType, &numComp);
      text = pixelType;
      if (numComp == 1)
        {
        SetPixelType(SCALAR);
        }
      else
        {
        SetPixelType(VECTOR);
        }
      if ( text.find("float") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(FLOAT);
        }
      else if ( text.find("double") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(DOUBLE);
        }
      else if ( text.find("unsigned_char") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(UCHAR);
        }
      else if ( text.find("char") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(CHAR);
        }
      else if ( text.find("unsigned_short") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(USHORT);
        }
      else if ( text.find("short") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(SHORT);
        }
      else if ( text.find("unsigned_int") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(UINT);
        }
      else if ( text.find("int") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(INT);
        }
      else if ( text.find("unsigned_long") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(ULONG);
        }
      else if ( text.find("long") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(LONG);
        }
      else
        {
        itkExceptionMacro(<<"Unrecognized type");
        }
      file.getline(line,255);
      text = line;

      }//found scalars

    }
}

void VTKImageIO::Read(void* buffer)
{
  std::ifstream file;

  this->InternalReadImageInformation(file);

  //We are positioned at the data. The data is read depending on whether
  //it is ASCII or binary.
  if ( m_FileType == ASCII )
    {
    this->ReadBufferAsASCII(file, buffer, this->GetComponentType(),
                            this->GetImageSizeInComponents());
    }
  else
    {
    file.read(static_cast<char*>(buffer), this->GetImageSizeInBytes());
    int size = this->GetPixelSize();
    switch( size )
      {
      case 2:
        ByteSwapper<short>::SwapRangeFromSystemToBigEndian((short *)buffer, this->GetImageSizeInComponents() );
        break;
      case 4:
        ByteSwapper<float>::SwapRangeFromSystemToBigEndian((float *)buffer, this->GetImageSizeInComponents() );
        break;
      case 8:
        ByteSwapper<double>::SwapRangeFromSystemToBigEndian((double *)buffer, this->GetImageSizeInComponents() );
        break;
      }
    }
}

void VTKImageIO::ReadImageInformation()
{
  std::ifstream file;
  this->InternalReadImageInformation(file);
}

bool VTKImageIO::CanWriteFile( const char* name )
{
  std::string filename = name;
  if ( filename != "" &&
       filename.find(".vtk") < filename.length() )
    {
    return true;
    }
  return false;
}

void VTKImageIO::Write(const void* buffer)
{
  std::ofstream file;
  if ( ! this->OpenVTKFileForWriting(file,m_FileName.c_str()) )
    {
    return;
    }

  // Check the image region for proper dimensions, etc.
  unsigned int numDims = this->GetNumberOfDimensions();
  if ( numDims < 2 || numDims > 3 )
    {
    itkExceptionMacro(<<"VTK Writer can only write 2 or 3-dimensional images");
    return;
    }
  ImageIORegion ioRegion = this->GetIORegion();

  // Write the VTK header information
  file << "# vtk DataFile Version 3.0\n";
  file << "VTK File Generated by Insight Segmentation and Registration Toolkit (ITK)\n";

  if ( this->GetFileType() == ASCII ) { file << "ASCII\n"; }
  else { file << "BINARY\n"; }

  // Write characteristics of the data
  file << "DATASET STRUCTURED_POINTS\n";
  if ( numDims == 2 )
    {
    file << "DIMENSIONS " << this->GetDimensions(0) << " "
         << this->GetDimensions(1) << " 1\n";
    file << "SPACING " << m_Spacing[0] << " " << m_Spacing[1] << " 1.0\n";
    file << "ORIGIN " << m_Origin[0] << " " << m_Origin[1] << " 0.0\n";
    }
  else //numDims == 3
    {
    file << "DIMENSIONS " << this->GetDimensions(0) << " "
         << this->GetDimensions(1) << " " << this->GetDimensions(2) << "\n";
    file << "SPACING " << m_Spacing[0] << " "
         << m_Spacing[1] << " " << m_Spacing[2] << "\n";
    file << "ORIGIN " << m_Origin[0] << " "
         << m_Origin[1] << " " << m_Origin[2] << "\n";
    }

  file << "POINT_DATA " << this->GetImageSizeInPixels() << "\n";
  file << "SCALARS scalars "
       << this->GetComponentTypeAsString(m_ComponentType) << " "
       << this->GetNumberOfComponents() << "\n";
  file << "LOOKUP_TABLE default\n";

  // Write the actual pixel data
  if ( m_FileType == ASCII )
    {
    this->WriteBufferAsASCII(file, buffer, this->GetComponentType(),
                             this->GetImageSizeInComponents());
    }
  else //binary
    {
    int size = this->GetPixelSize();
    const unsigned long int numbytes=this->GetImageSizeInBytes();
    char * tempmemory=new char[numbytes];
    memcpy(tempmemory,buffer,numbytes);
    switch( size )
      {
      case 2:
      {
      ByteSwapper<short>::SwapRangeFromSystemToBigEndian(reinterpret_cast<short *>(tempmemory), this->GetImageSizeInComponents() );
      }
      break;
      case 4:
      {
      ByteSwapper<float>::SwapRangeFromSystemToBigEndian(reinterpret_cast<float *>(tempmemory), this->GetImageSizeInComponents() );
      }
      break;
      case 8:
      {
      ByteSwapper<double>::SwapRangeFromSystemToBigEndian(reinterpret_cast<double *>(tempmemory), this->GetImageSizeInComponents() );
      }
      break;
      }
    file.write(static_cast<const char*>(tempmemory), this->GetImageSizeInBytes());
    delete [] tempmemory;
    }
}

void VTKImageIO::PrintSelf(std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);
}

} // end namespace itk
<commit_msg>BUG: Fix for bug 1676. VTKImageIO was byteswapping entire pixels instead of each component in a pixel. This would give wrong results for multi-component pixel data<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkVTKImageIO.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

  Portions of this code are covered under the VTK copyright.
  See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm 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 "itkVTKImageIO.h"
#include <stdio.h>
#include "itkByteSwapper.h"

namespace itk
{

VTKImageIO::VTKImageIO()
{
  this->SetNumberOfDimensions(2);
  m_ByteOrder = LittleEndian;
  m_FileType = Binary;

}

VTKImageIO::~VTKImageIO()
{
}

bool VTKImageIO::OpenVTKFileForReading(std::ifstream& os,
                                       const char* filename)

{
  // Make sure that we have a file to
  if ( filename == "" )
    {
    itkExceptionMacro(<<"A FileName must be specified.");
    return false;
    }

  // Close file from any previous image
  if ( os.is_open() )
    {
    os.close();
    }

  // Open the new file for reading
  itkDebugMacro(<< "Initialize: opening file " << filename);

  // Actually open the file

#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
  const int openMode = std::ios::in|std::ios::binary;
#elif ( defined(__GNUC__) && __GNUC__ >= 3 ) || defined (__MWERKS__) || defined (__INTEL_COMPILER) || defined (__MINGW32__) || defined(__CYGWIN__)
  const std::ios_base::openmode openMode = std::ios::in;
#else
  const int openMode = std::ios::in;
#endif
  os.open(filename, openMode);
  if ( os.fail() )
    {
    itkExceptionMacro(<< "Could not open file for reading: " << filename);
    return false;
    }

  return true;
}

bool VTKImageIO::OpenVTKFileForWriting(std::ofstream& os,
                                       const char* filename)

{
  // Make sure that we have a file to
  if ( filename == "" )
    {
    itkExceptionMacro(<<"A FileName must be specified.");
    return false;
    }

  // Create the file. This is required on some older sgi's
  std::ofstream tFile(filename,std::ios::out);
  tFile.close();

  // Close file from any previous image
  if ( os.is_open() )
    {
    os.close();
    }

  // Open the new file for writing
  itkDebugMacro(<< "Initialize: opening file " << filename);

  // Actually open the file
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
  const int openMode = std::ios::out|std::ios::binary;
#elif (defined(__GNUC__) && __GNUC__ >= 3) || defined (__MWERKS__) || defined (__INTEL_COMPILER) || defined (__MINGW32__) || defined(__CYGWIN__)
  const std::ios_base::openmode openMode =std::ios::out;
#else
  const int openMode = std::ios::out;
#endif
  os.open(filename, openMode);
  if ( os.fail() )
    {
    itkExceptionMacro(<< "Could not open file for writing: " << filename);
    return false;
    }

  return true;
}

bool VTKImageIO::CanReadFile(const char* filename)
{
  std::ifstream file;
  char buffer[256];
  std::string fname(filename);

  if ( fname.find(".vtk") >= fname.length() )
    {
    return false;
    }

  if ( ! this->OpenVTKFileForReading(file, filename) )
    {
    return false;
    }

  // Check to see if its a vtk structured points file
  file.getline(buffer,255);
  file.getline(buffer,255);
  file.getline(buffer,255);
  file.getline(buffer,255);

  fname = buffer;

  if ( fname.find("STRUCTURED_POINTS") < fname.length() ||
       fname.find("structured_points") < fname.length() )
    {
    return true;
    }
  else
    {
    return false;
    }
}

void VTKImageIO::InternalReadImageInformation(std::ifstream& file)
{
  char line[255];
  std::string text;

  if ( ! this->OpenVTKFileForReading(file, m_FileName.c_str()) )
    {
    itkExceptionMacro(<< "Cannot read requested file");
    }

  file.getline(line,255);
  file.getline(line,255);
  file.getline(line,255);
  text = line;
  if ( text.find("ASCII") < text.length() ||
       text.find("ascii") < text.length() )
    {
    this->SetFileTypeToASCII();
    }
  else if ( text.find("BINARY") < text.length() ||
            text.find("binary") < text.length() )
    {
    this->SetFileTypeToBinary();
    }
  else
    {
    itkExceptionMacro(<< "Unrecognized type");
    }
  file.getline(line,255);
  text = line;
  if ( text.find("STRUCTURED_POINTS") >= text.length() &&
       text.find("structured_points") >= text.length() )
    {
    itkExceptionMacro(<< "Not structured points, can't read");
    }

  //extract dimensions, spacing, origin
  unsigned int dims[3];
  float spacing[3];
  float origin[3];
  file.getline(line,255);
  text = line;

  // set values in case we don't find them
  this->SetNumberOfDimensions(3);
  m_Spacing[0] = 1.0;
  m_Spacing[1] = 1.0;
  m_Spacing[2] = 1.0;
  m_Origin[0] = 0.0;
  m_Origin[1] = 0.0;
  m_Origin[2] = 0.0;

  if ( text.find("DIMENSIONS") < text.length() ||
       text.find("dimensions") < text.length() )
    {
    sscanf(line, "%*s %d %d %d", dims, dims+1, dims+2);
    if ( dims[2] <= 1 )
      {
      this->SetNumberOfDimensions(2);
      }
    else
      {
      this->SetNumberOfDimensions(3);
      }
    for ( unsigned int i=0; i < m_NumberOfDimensions; i++ )
      {
      m_Dimensions[i] = dims[i];
      }
    }
  else
    {
    itkExceptionMacro(<<"No dimensions defined");
    }

  for ( bool readScalars=false; !readScalars; )
    {
    file.getline(line,255);
    text = line;

    if ( text.find("SPACING") < text.length() ||
         text.find("spacing") < text.length() )
      {
      sscanf(line, "%*s %f %f %f", spacing, spacing+1, spacing+2);
      for ( unsigned int i=0; i < m_NumberOfDimensions; i++ )
        {
        m_Spacing[i] = spacing[i];
        }
      }

    else if ( text.find("ORIGIN") < text.length() ||
              text.find("origin") < text.length() )
      {
      sscanf(line, "%*s %f %f %f", origin, origin+1, origin+2);
      for ( unsigned int i=0; i < m_NumberOfDimensions; i++ )
        {
        m_Origin[i] = origin[i];
        }
      }

    else if ( text.find("COLOR_SCALARS") < text.length() ||
              text.find("color_scalars") < text.length() )
      {
      readScalars = true;

      int numComp = 1;
      sscanf(line, "%*s %*s %d", &numComp);
      if (numComp == 1)
        {
        SetPixelType(SCALAR);
        }
      else
        {
        SetPixelType(VECTOR);
        }
      if ( this->GetFileType() == ASCII )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(FLOAT);
        }
      else
        {
        SetNumberOfComponents(numComp);
        SetComponentType(UCHAR);
        }
      }

    else if ( text.find("SCALARS") < text.length() ||
              text.find("scalars") < text.length() )
      {
      readScalars = true;

      char pixelType[256];
      int numComp = 1;
      sscanf(line, "%*s %*s %s %d", pixelType, &numComp);
      text = pixelType;
      if (numComp == 1)
        {
        SetPixelType(SCALAR);
        }
      else
        {
        SetPixelType(VECTOR);
        }
      if ( text.find("float") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(FLOAT);
        }
      else if ( text.find("double") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(DOUBLE);
        }
      else if ( text.find("unsigned_char") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(UCHAR);
        }
      else if ( text.find("char") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(CHAR);
        }
      else if ( text.find("unsigned_short") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(USHORT);
        }
      else if ( text.find("short") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(SHORT);
        }
      else if ( text.find("unsigned_int") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(UINT);
        }
      else if ( text.find("int") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(INT);
        }
      else if ( text.find("unsigned_long") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(ULONG);
        }
      else if ( text.find("long") < text.length() )
        {
        SetNumberOfComponents(numComp);
        SetComponentType(LONG);
        }
      else
        {
        itkExceptionMacro(<<"Unrecognized type");
        }
      file.getline(line,255);
      text = line;

      }//found scalars

    }
}

void VTKImageIO::Read(void* buffer)
{
  std::ifstream file;

  this->InternalReadImageInformation(file);

  //We are positioned at the data. The data is read depending on whether
  //it is ASCII or binary.
  if ( m_FileType == ASCII )
    {
    this->ReadBufferAsASCII(file, buffer, this->GetComponentType(),
                            this->GetImageSizeInComponents());
    }
  else
    {
    file.read(static_cast<char*>(buffer), this->GetImageSizeInBytes());
    int size = this->GetComponentSize();
    switch( size )
      {
      case 2:
        ByteSwapper<short>::SwapRangeFromSystemToBigEndian((short *)buffer, this->GetImageSizeInComponents() );
        break;
      case 4:
        ByteSwapper<float>::SwapRangeFromSystemToBigEndian((float *)buffer, this->GetImageSizeInComponents() );
        break;
      case 8:
        ByteSwapper<double>::SwapRangeFromSystemToBigEndian((double *)buffer, this->GetImageSizeInComponents() );
        break;
      }
    }
}

void VTKImageIO::ReadImageInformation()
{
  std::ifstream file;
  this->InternalReadImageInformation(file);
}

bool VTKImageIO::CanWriteFile( const char* name )
{
  std::string filename = name;
  if ( filename != "" &&
       filename.find(".vtk") < filename.length() )
    {
    return true;
    }
  return false;
}

void VTKImageIO::Write(const void* buffer)
{
  std::ofstream file;
  if ( ! this->OpenVTKFileForWriting(file,m_FileName.c_str()) )
    {
    return;
    }

  // Check the image region for proper dimensions, etc.
  unsigned int numDims = this->GetNumberOfDimensions();
  if ( numDims < 2 || numDims > 3 )
    {
    itkExceptionMacro(<<"VTK Writer can only write 2 or 3-dimensional images");
    return;
    }
  ImageIORegion ioRegion = this->GetIORegion();

  // Write the VTK header information
  file << "# vtk DataFile Version 3.0\n";
  file << "VTK File Generated by Insight Segmentation and Registration Toolkit (ITK)\n";

  if ( this->GetFileType() == ASCII ) { file << "ASCII\n"; }
  else { file << "BINARY\n"; }

  // Write characteristics of the data
  file << "DATASET STRUCTURED_POINTS\n";
  if ( numDims == 2 )
    {
    file << "DIMENSIONS " << this->GetDimensions(0) << " "
         << this->GetDimensions(1) << " 1\n";
    file << "SPACING " << m_Spacing[0] << " " << m_Spacing[1] << " 1.0\n";
    file << "ORIGIN " << m_Origin[0] << " " << m_Origin[1] << " 0.0\n";
    }
  else //numDims == 3
    {
    file << "DIMENSIONS " << this->GetDimensions(0) << " "
         << this->GetDimensions(1) << " " << this->GetDimensions(2) << "\n";
    file << "SPACING " << m_Spacing[0] << " "
         << m_Spacing[1] << " " << m_Spacing[2] << "\n";
    file << "ORIGIN " << m_Origin[0] << " "
         << m_Origin[1] << " " << m_Origin[2] << "\n";
    }

  file << "POINT_DATA " << this->GetImageSizeInPixels() << "\n";
  file << "SCALARS scalars "
       << this->GetComponentTypeAsString(m_ComponentType) << " "
       << this->GetNumberOfComponents() << "\n";
  file << "LOOKUP_TABLE default\n";

  // Write the actual pixel data
  if ( m_FileType == ASCII )
    {
    this->WriteBufferAsASCII(file, buffer, this->GetComponentType(),
                             this->GetImageSizeInComponents());
    }
  else //binary
    {
    int size = this->GetComponentSize();
    const unsigned long int numbytes=this->GetImageSizeInBytes();
    char * tempmemory=new char[numbytes];
    memcpy(tempmemory,buffer,numbytes);
    switch( size )
      {
      case 2:
      {
      ByteSwapper<short>::SwapRangeFromSystemToBigEndian(reinterpret_cast<short *>(tempmemory), this->GetImageSizeInComponents() );
      }
      break;
      case 4:
      {
      ByteSwapper<float>::SwapRangeFromSystemToBigEndian(reinterpret_cast<float *>(tempmemory), this->GetImageSizeInComponents() );
      }
      break;
      case 8:
      {
      ByteSwapper<double>::SwapRangeFromSystemToBigEndian(reinterpret_cast<double *>(tempmemory), this->GetImageSizeInComponents() );
      }
      break;
      }
    file.write(static_cast<const char*>(tempmemory), this->GetImageSizeInBytes());
    delete [] tempmemory;
    }
}

void VTKImageIO::PrintSelf(std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);
}

} // end namespace itk
<|endoftext|>


<commit_before>//===-- X86WinCOFFObjectWriter.cpp - X86 Win COFF Writer ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/X86FixupKinds.h"
#include "MCTargetDesc/X86MCTargetDesc.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/MCWinCOFFObjectWriter.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/ErrorHandling.h"

using namespace llvm;

namespace llvm {
  class MCObjectWriter;
}

namespace {
  class X86WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {
    const bool Is64Bit;

  public:
    X86WinCOFFObjectWriter(bool Is64Bit_);
    virtual ~X86WinCOFFObjectWriter();

    unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
                          bool IsCrossSection) const override;
  };
}

X86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit_)
  : MCWinCOFFObjectTargetWriter(Is64Bit_ ? COFF::IMAGE_FILE_MACHINE_AMD64 :
                                COFF::IMAGE_FILE_MACHINE_I386),
    Is64Bit(Is64Bit_) {}

X86WinCOFFObjectWriter::~X86WinCOFFObjectWriter() {}

unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target,
                                              const MCFixup &Fixup,
                                              bool IsCrossSection) const {
  unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind();

  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();

  switch (FixupKind) {
  case FK_PCRel_4:
  case X86::reloc_riprel_4byte:
  case X86::reloc_riprel_4byte_movq_load:
    return Is64Bit ? COFF::IMAGE_REL_AMD64_REL32 : COFF::IMAGE_REL_I386_REL32;
  case FK_Data_4:
  case X86::reloc_signed_4byte:
    if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
      return Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32NB :
                       COFF::IMAGE_REL_I386_DIR32NB;
    return Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32 : COFF::IMAGE_REL_I386_DIR32;
  case FK_Data_8:
    if (Is64Bit)
      return COFF::IMAGE_REL_AMD64_ADDR64;
    llvm_unreachable("unsupported relocation type");
  case FK_SecRel_2:
    return Is64Bit ? COFF::IMAGE_REL_AMD64_SECTION
                   : COFF::IMAGE_REL_I386_SECTION;
  case FK_SecRel_4:
    return Is64Bit ? COFF::IMAGE_REL_AMD64_SECREL : COFF::IMAGE_REL_I386_SECREL;
  default:
    llvm_unreachable("unsupported relocation type");
  }
}

MCObjectWriter *llvm::createX86WinCOFFObjectWriter(raw_ostream &OS,
                                                   bool Is64Bit) {
  MCWinCOFFObjectTargetWriter *MOTW = new X86WinCOFFObjectWriter(Is64Bit);
  return createWinCOFFObjectWriter(MOTW, OS);
}
<commit_msg>X86: Split the relocation selection up<commit_after>//===-- X86WinCOFFObjectWriter.cpp - X86 Win COFF Writer ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/X86FixupKinds.h"
#include "MCTargetDesc/X86MCTargetDesc.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/MCWinCOFFObjectWriter.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/ErrorHandling.h"

using namespace llvm;

namespace llvm {
  class MCObjectWriter;
}

namespace {
  class X86WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {
  public:
    X86WinCOFFObjectWriter(bool Is64Bit);
    virtual ~X86WinCOFFObjectWriter();

    unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
                          bool IsCrossSection) const override;
  };
}

X86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit)
    : MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_AMD64
                                          : COFF::IMAGE_FILE_MACHINE_I386) {}

X86WinCOFFObjectWriter::~X86WinCOFFObjectWriter() {}

unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target,
                                              const MCFixup &Fixup,
                                              bool IsCrossSection) const {
  unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind();

  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();

  if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64) {
    switch (FixupKind) {
    case FK_PCRel_4:
    case X86::reloc_riprel_4byte:
    case X86::reloc_riprel_4byte_movq_load:
      return COFF::IMAGE_REL_AMD64_REL32;
    case FK_Data_4:
    case X86::reloc_signed_4byte:
      if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
        return COFF::IMAGE_REL_AMD64_ADDR32NB;
      return COFF::IMAGE_REL_AMD64_ADDR32;
    case FK_Data_8:
      return COFF::IMAGE_REL_AMD64_ADDR64;
    case FK_SecRel_2:
      return COFF::IMAGE_REL_AMD64_SECTION;
    case FK_SecRel_4:
      return COFF::IMAGE_REL_AMD64_SECREL;
    default:
      llvm_unreachable("unsupported relocation type");
    }
  } else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386) {
    switch (FixupKind) {
    case FK_PCRel_4:
    case X86::reloc_riprel_4byte:
    case X86::reloc_riprel_4byte_movq_load:
      return COFF::IMAGE_REL_I386_REL32;
    case FK_Data_4:
    case X86::reloc_signed_4byte:
      if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
        return COFF::IMAGE_REL_I386_DIR32NB;
      return COFF::IMAGE_REL_I386_DIR32;
    case FK_SecRel_2:
      return COFF::IMAGE_REL_I386_SECTION;
    case FK_SecRel_4:
      return COFF::IMAGE_REL_I386_SECREL;
    default:
      llvm_unreachable("unsupported relocation type");
    }
  } else
    llvm_unreachable("Unsupported COFF machine type.");
}

MCObjectWriter *llvm::createX86WinCOFFObjectWriter(raw_ostream &OS,
                                                   bool Is64Bit) {
  MCWinCOFFObjectTargetWriter *MOTW = new X86WinCOFFObjectWriter(Is64Bit);
  return createWinCOFFObjectWriter(MOTW, OS);
}
<|endoftext|>


<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 "otbCurlHelper.h"
#include "otbMacro.h"

#ifdef OTB_USE_CURL
#include <curl/curl.h>
#include <cstring>
#endif

namespace otb
{

int CurlHelper::TestUrlAvailability(const std::string& url) const
{
#ifdef OTB_USE_CURL
  // Set up a curl request
  CURL *   curl;
  CURLcode res = CURL_LAST;
  curl = curl_easy_init();

  // Set up the browser
  std::string browser =
    "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11";

  if (curl)
    {
    curl_easy_setopt(curl, CURLOPT_USERAGENT, browser.data());
    curl_easy_setopt(curl, CURLOPT_URL, url.data());
    // Set the dummy write function
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Self::curlDummyWriteFunction);
    curl_easy_setopt(curl, CURLOPT_MAXFILESIZE, 1);

    // Perform requet
    res = curl_easy_perform(curl);
    }
  return res;
#else
  otbMsgDevMacro(<< "Curl is not available, compile with OTB_USE_CURL to ON");
  return -1;
#endif
}

int CurlHelper::RetrieveFile(const std::ostringstream& urlStream, std::string filename) const
{
  return RetrieveFile(urlStream.str(), filename);
}

int CurlHelper::RetrieveFile(const std::string& urlString, std::string filename) const
{
#ifdef OTB_USE_CURL
  CURL *   curl;
  CURLcode res = CURL_LAST;

  FILE* output_file = fopen(filename.c_str(), "w");
  curl = curl_easy_init();

  char url[256];
  strcpy(url, urlString.data());

//   std::cout << url << std::endl;
  if (curl)
    {
    std::vector<char> chunk;
    curl_easy_setopt(curl, CURLOPT_URL, url);

    // Set 5s timeout
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5);

    curl_easy_setopt(curl, CURLOPT_WRITEDATA, output_file);
    res = curl_easy_perform(curl);

    fclose(output_file);
    /* always cleanup */
    curl_easy_cleanup(curl);
    }
  return res;
#else
  otbMsgDevMacro(<< "Curl is not available, compile with OTB_USE_CURL to ON");
  return -1;
#endif
}

int CurlHelper::RetrieveFileMulti(const std::vector<std::string>& listURLs,
                                  const std::vector<std::string>& listFilename,
                                  int maxConnect) const
{
#ifdef OTB_USE_CURL
#ifdef OTB_CURL_MULTI_AVAILABLE
  otbMsgDevMacro(<< "Using curl multi");
  std::string  m_Browser = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11";

  CURLM *             multiHandle;
  std::vector<CURL *> listCurlHandles;
  std::vector<FILE *> listFiles;

  std::vector<std::string>::const_iterator filename;
  filename = listFilename.begin();
  while (filename != listFilename.end() )
    {
    FILE* lOutputFile = fopen((*filename).c_str(), "w");
    if (lOutputFile == NULL)
    {
    itkExceptionMacro(<< "otbCurlHelper: bad file name: " << (*filename).c_str());
    }

    // Add file to vector
    listFiles.push_back(lOutputFile);
    ++filename;
    }

  // Initialize curl multi handle
  multiHandle = curl_multi_init();

  if (!multiHandle)
    {
    itkExceptionMacro(<< "otbCurlHelper: Curl multi handle init error.");
    }

  listCurlHandles.clear();

  // Initialize curl handle

  std::vector<std::string>::const_iterator url;
  std::vector<FILE *>::const_iterator file;
  url = listURLs.begin();
  file = listFiles.begin();
  while ( (url != listURLs.end()) && (file != listFiles.end() ))
    {
    CURL * lEasyHandle;
    lEasyHandle = curl_easy_init();

    if (!lEasyHandle)
      {
      itkExceptionMacro(<< "otbCurlHelper: Curl easy handle init error.");
      }

    // Param easy handle
    curl_easy_setopt(lEasyHandle, CURLOPT_USERAGENT, m_Browser.data());
    curl_easy_setopt(lEasyHandle, CURLOPT_URL, (*url).data());
    curl_easy_setopt(lEasyHandle, CURLOPT_WRITEDATA, *file);

    // Add easy handle to multi handle
    curl_multi_add_handle(multiHandle, lEasyHandle);

    // Add hanle to vector
    listCurlHandles.push_back(lEasyHandle);
    ++url;
    ++file;
    }

//fetch tiles
  // Configure multi handle - set the maximum connections
  curl_multi_setopt(multiHandle, CURLMOPT_MAXCONNECTS, maxConnect);
  curl_multi_setopt(multiHandle, CURLMOPT_PIPELINING, 0);

  // Perform
  int lStillRunning;

  while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multiHandle, &lStillRunning));

  // Now get that URL
  while (lStillRunning)
    {
    struct timeval timeout;
    int            rc; // Return code

    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int    maxfd;

    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    /* set a suitable timeout to play around with */
    timeout.tv_sec = 0;
    timeout.tv_usec = 1;

    /* get file descriptors from the transfers */
    curl_multi_fdset(multiHandle, &fdread, &fdwrite, &fdexcep, &maxfd);

    rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);

    switch (rc)
      {
    case -1:
      /* select error */
      break;
    case 0:
    /* timeout */
    default:
      /* timeout or readable/writable sockets */
      while (
        CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multiHandle, &lStillRunning)
        )
        ;
      break;
      }
    }

  int      remaining_msgs = 1;
  int      error = 0;
  CURLMsg *msg;
  while (remaining_msgs)
    {
    msg = curl_multi_info_read(multiHandle, &remaining_msgs);
    if (msg != NULL)
      {
      if (CURLE_OK != msg->data.result) error = 1;
      }
    }

  if (error != 0)
    {
    itkExceptionMacro(<< "otbCurlHelper: Error occurs while perform Multi handle");
    }

// Cleanup

  // Close files
  for (unsigned int currentFile = 0; currentFile < listFiles.size(); currentFile++)
    {
    fclose(listFiles[currentFile]);
    }
  listFiles.clear();

  // Cleanup easy handles
  for (unsigned int currentHandle = 0; currentHandle < listCurlHandles.size(); currentHandle++)
    {
    curl_easy_cleanup(listCurlHandles[currentHandle]);
    }
  listCurlHandles.clear();

  // Cleanup multi handle
  curl_multi_cleanup(multiHandle);

#else
  //fallback on non curl multi
  otbMsgDevMacro(<< "Curl multi is not available, fallback on standard");
  std::vector<std::string>::const_iterator url;
  std::vector<std::string>::const_iterator file;
  url = listURLs.begin();
  file = listFilename.begin();
  while ( (url != listURLs.end()) && (file != listFilename.end() ))
    {
    RetrieveFile(*url, *file);
    }
#endif
#else
  otbMsgDevMacro(<< "Curl is not available, compile with OTB_USE_CURL to ON");
  return -1;
#endif
}

}
<commit_msg>WRG:add return statement to the RetrieveFileMulticurl function<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 "otbCurlHelper.h"
#include "otbMacro.h"

#ifdef OTB_USE_CURL
#include <curl/curl.h>
#include <cstring>
#endif

namespace otb
{

int CurlHelper::TestUrlAvailability(const std::string& url) const
{
#ifdef OTB_USE_CURL
  // Set up a curl request
  CURL *   curl;
  CURLcode res = CURL_LAST;
  curl = curl_easy_init();

  // Set up the browser
  std::string browser =
    "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11";

  if (curl)
    {
    curl_easy_setopt(curl, CURLOPT_USERAGENT, browser.data());
    curl_easy_setopt(curl, CURLOPT_URL, url.data());
    // Set the dummy write function
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Self::curlDummyWriteFunction);
    curl_easy_setopt(curl, CURLOPT_MAXFILESIZE, 1);

    // Perform requet
    res = curl_easy_perform(curl);
    }
  return res;
#else
  otbMsgDevMacro(<< "Curl is not available, compile with OTB_USE_CURL to ON");
  return -1;
#endif
}

int CurlHelper::RetrieveFile(const std::ostringstream& urlStream, std::string filename) const
{
  return RetrieveFile(urlStream.str(), filename);
}

int CurlHelper::RetrieveFile(const std::string& urlString, std::string filename) const
{
#ifdef OTB_USE_CURL
  CURL *   curl;
  CURLcode res = CURL_LAST;

  FILE* output_file = fopen(filename.c_str(), "w");
  curl = curl_easy_init();

  char url[256];
  strcpy(url, urlString.data());

//   std::cout << url << std::endl;
  if (curl)
    {
    std::vector<char> chunk;
    curl_easy_setopt(curl, CURLOPT_URL, url);

    // Set 5s timeout
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5);

    curl_easy_setopt(curl, CURLOPT_WRITEDATA, output_file);
    res = curl_easy_perform(curl);

    fclose(output_file);
    /* always cleanup */
    curl_easy_cleanup(curl);
    }
  return res;
#else
  otbMsgDevMacro(<< "Curl is not available, compile with OTB_USE_CURL to ON");
  return -1;
#endif
}

int CurlHelper::RetrieveFileMulti(const std::vector<std::string>& listURLs,
                                  const std::vector<std::string>& listFilename,
                                  int maxConnect) const
{
#ifdef OTB_USE_CURL
#ifdef OTB_CURL_MULTI_AVAILABLE
  otbMsgDevMacro(<< "Using curl multi");
  std::string  m_Browser = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11";

  CURLM *             multiHandle;
  std::vector<CURL *> listCurlHandles;
  std::vector<FILE *> listFiles;

  std::vector<std::string>::const_iterator filename;
  filename = listFilename.begin();
  while (filename != listFilename.end() )
    {
    FILE* lOutputFile = fopen((*filename).c_str(), "w");
    if (lOutputFile == NULL)
    {
    itkExceptionMacro(<< "otbCurlHelper: bad file name: " << (*filename).c_str());
    }

    // Add file to vector
    listFiles.push_back(lOutputFile);
    ++filename;
    }

  // Initialize curl multi handle
  multiHandle = curl_multi_init();

  if (!multiHandle)
    {
    itkExceptionMacro(<< "otbCurlHelper: Curl multi handle init error.");
    }

  listCurlHandles.clear();

  // Initialize curl handle

  std::vector<std::string>::const_iterator url;
  std::vector<FILE *>::const_iterator file;
  url = listURLs.begin();
  file = listFiles.begin();
  while ( (url != listURLs.end()) && (file != listFiles.end() ))
    {
    CURL * lEasyHandle;
    lEasyHandle = curl_easy_init();

    if (!lEasyHandle)
      {
      itkExceptionMacro(<< "otbCurlHelper: Curl easy handle init error.");
      }

    // Param easy handle
    curl_easy_setopt(lEasyHandle, CURLOPT_USERAGENT, m_Browser.data());
    curl_easy_setopt(lEasyHandle, CURLOPT_URL, (*url).data());
    curl_easy_setopt(lEasyHandle, CURLOPT_WRITEDATA, *file);

    // Add easy handle to multi handle
    curl_multi_add_handle(multiHandle, lEasyHandle);

    // Add hanle to vector
    listCurlHandles.push_back(lEasyHandle);
    ++url;
    ++file;
    }

//fetch tiles
  // Configure multi handle - set the maximum connections
  curl_multi_setopt(multiHandle, CURLMOPT_MAXCONNECTS, maxConnect);
  curl_multi_setopt(multiHandle, CURLMOPT_PIPELINING, 0);

  // Perform
  int lStillRunning;

  while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multiHandle, &lStillRunning));

  // Now get that URL
  while (lStillRunning)
    {
    struct timeval timeout;
    int            rc; // Return code

    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int    maxfd;

    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    /* set a suitable timeout to play around with */
    timeout.tv_sec = 0;
    timeout.tv_usec = 1;

    /* get file descriptors from the transfers */
    curl_multi_fdset(multiHandle, &fdread, &fdwrite, &fdexcep, &maxfd);

    rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);

    switch (rc)
      {
    case -1:
      /* select error */
      break;
    case 0:
    /* timeout */
    default:
      /* timeout or readable/writable sockets */
      while (
        CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multiHandle, &lStillRunning)
        )
        ;
      break;
      }
    }

  int      remaining_msgs = 1;
  int      error = 0;
  CURLMsg *msg;
  while (remaining_msgs)
    {
    msg = curl_multi_info_read(multiHandle, &remaining_msgs);
    if (msg != NULL)
      {
      if (CURLE_OK != msg->data.result) error = 1;
      }
    }

  if (error != 0)
    {
    itkExceptionMacro(<< "otbCurlHelper: Error occurs while perform Multi handle");
    }

// Cleanup

  // Close files
  for (unsigned int currentFile = 0; currentFile < listFiles.size(); currentFile++)
    {
    fclose(listFiles[currentFile]);
    }
  listFiles.clear();

  // Cleanup easy handles
  for (unsigned int currentHandle = 0; currentHandle < listCurlHandles.size(); currentHandle++)
    {
    curl_easy_cleanup(listCurlHandles[currentHandle]);
    }
  listCurlHandles.clear();

  // Cleanup multi handle
  return curl_multi_cleanup(multiHandle);
#else
  //fallback on non curl multi
  otbMsgDevMacro(<< "Curl multi is not available, fallback on standard");
  std::vector<std::string>::const_iterator url;
  std::vector<std::string>::const_iterator file;
  url = listURLs.begin();
  file = listFilename.begin();
  int res = 0;
  while ( (url != listURLs.end()) && (file != listFilename.end() ))
    {
    res = RetrieveFile(*url, *file);
    }
  return res;
#endif
#else
  otbMsgDevMacro(<< "Curl is not available, compile with OTB_USE_CURL to ON");
  return -1;
#endif
}

}
<|endoftext|>


<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 "otbDEMHandler.h"
#include "otbMacro.h"

#include "elevation/ossimElevManager.h"
#include "base/ossimGeoidManager.h"
#include "base/ossimFilename.h"
#include "base/ossimDirectory.h"
#include "base/ossimGeoidEgm96.h"

namespace otb
{

DEMHandler
::DEMHandler():
  m_ElevManager(ossimElevManager::instance())
{
}

void
DEMHandler
::OpenDEMDirectory(const char* DEMDirectory)
{
  m_Mutex.Lock();
  ossimFilename ossimDEMDir;
  ossimDEMDir=ossimFilename(DEMDirectory);

  ossimDirectory od(DEMDirectory);
  if (!m_ElevManager->loadElevationPath(ossimDEMDir))
  {
    m_Mutex.Unlock();
    itkExceptionMacro("Failed to open DEM Directory: "<<ossimDEMDir);
  }
  m_Mutex.Unlock();
}

void
DEMHandler
::OpenGeoidFile(const char* geoidFile)
{
  ossimFilename geoid(geoidFile);
  ossimGeoid* geoidPtr = new ossimGeoidEgm96(geoid);
  if (geoidPtr->getErrorStatus() == ossimErrorCodes::OSSIM_OK)
  {
     m_Mutex.Lock();
     ossimGeoidManager::instance()->addGeoid(geoidPtr);
     m_Mutex.Unlock();
  }
}

double
DEMHandler
::GetHeightAboveMSL(const PointType& geoPoint) const
{
  double height;
  ossimGpt ossimWorldPoint;
  ossimWorldPoint.lon=geoPoint[0];
  ossimWorldPoint.lat=geoPoint[1];
  m_Mutex.Lock();
  height=m_ElevManager->getHeightAboveMSL(ossimWorldPoint);
  m_Mutex.Unlock();
  return height;
}

double
DEMHandler
::GetHeightAboveEllipsoid(const PointType& geoPoint) const
{
  double height;
  ossimGpt ossimWorldPoint;
  ossimWorldPoint.lon=geoPoint[0];
  ossimWorldPoint.lat=geoPoint[1];
  m_Mutex.Lock();
  height=m_ElevManager->getHeightAboveEllipsoid(ossimWorldPoint);
  m_Mutex.Unlock();
  return height;
}

void
DEMHandler
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  Superclass::PrintSelf(os,indent);
  os << indent << "DEMHandler" << std::endl;
}

} // namespace otb
<commit_msg>BUG: mutex already within ossim<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 "otbDEMHandler.h"
#include "otbMacro.h"

#include "elevation/ossimElevManager.h"
#include "base/ossimGeoidManager.h"
#include "base/ossimFilename.h"
#include "base/ossimDirectory.h"
#include "base/ossimGeoidEgm96.h"

namespace otb
{

DEMHandler
::DEMHandler():
  m_ElevManager(ossimElevManager::instance())
{
}

void
DEMHandler
::OpenDEMDirectory(const char* DEMDirectory)
{
  m_Mutex.Lock();
  ossimFilename ossimDEMDir;
  ossimDEMDir=ossimFilename(DEMDirectory);

  ossimDirectory od(DEMDirectory);
  if (!m_ElevManager->loadElevationPath(ossimDEMDir))
  {
    m_Mutex.Unlock();
    itkExceptionMacro("Failed to open DEM Directory: "<<ossimDEMDir);
  }
  m_Mutex.Unlock();
}

void
DEMHandler
::OpenGeoidFile(const char* geoidFile)
{
  ossimFilename geoid(geoidFile);
  ossimGeoid* geoidPtr = new ossimGeoidEgm96(geoid);
  if (geoidPtr->getErrorStatus() == ossimErrorCodes::OSSIM_OK)
  {
     m_Mutex.Lock();
     ossimGeoidManager::instance()->addGeoid(geoidPtr);
     m_Mutex.Unlock();
  }
}

double
DEMHandler
::GetHeightAboveMSL(const PointType& geoPoint) const
{
  double height;
  ossimGpt ossimWorldPoint;
  ossimWorldPoint.lon=geoPoint[0];
  ossimWorldPoint.lat=geoPoint[1];
//   m_Mutex.Lock();
  height=m_ElevManager->getHeightAboveMSL(ossimWorldPoint);
//   m_Mutex.Unlock();
  return height;
}

double
DEMHandler
::GetHeightAboveEllipsoid(const PointType& geoPoint) const
{
  double height;
  ossimGpt ossimWorldPoint;
  ossimWorldPoint.lon=geoPoint[0];
  ossimWorldPoint.lat=geoPoint[1];
  m_Mutex.Lock();
  height=m_ElevManager->getHeightAboveEllipsoid(ossimWorldPoint);
  m_Mutex.Unlock();
  return height;
}

void
DEMHandler
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  Superclass::PrintSelf(os,indent);
  os << indent << "DEMHandler" << std::endl;
}

} // namespace otb
<|endoftext|>


<commit_before>#ifndef STAN__AGRAD__REV__FUNCTIONS__LOG_MIX_HPP
#define STAN__AGRAD__REV__FUNCTIONS__LOG_MIX_HPP

#include <cmath>
#include <stan/agrad/rev.hpp>
#include <stan/error_handling/scalar/check_bounded.hpp>
#include <stan/error_handling/scalar/check_not_nan.hpp>
#include <stan/math/functions/log_sum_exp.hpp>
#include <stan/math/functions/log1m.hpp>
#include <stan/math/functions/value_of.hpp>
#include <stan/agrad/rev/functions/value_of.hpp>
#include <stan/meta/traits.hpp>
#include <stan/agrad/partials_vari.hpp>

namespace stan {

  namespace agrad {

    inline
    void log_mix_deriv_inter_helper(const double& theta_val,
                                    const double& lambda1_val,
                                    const double& lambda2_val,
                                    double& one_m_exp_lam2_m_lam1,
                                    double& one_m_t_prod_exp_lam2_m_lam1,
                                    double& one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1){
        using ::exp;
        double lam2_m_lam1 = lambda2_val - lambda1_val;
        double exp_lam2_m_lam1 = exp(lam2_m_lam1);
        one_m_exp_lam2_m_lam1 = 1 - exp_lam2_m_lam1;
        double one_m_t = 1 - theta_val;
        one_m_t_prod_exp_lam2_m_lam1 = one_m_t * exp_lam2_m_lam1;
        one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1
          = 1 / (theta_val + one_m_t_prod_exp_lam2_m_lam1);
    }

    template <typename T_theta,
              typename T_lambda1,
              typename T_lambda2>
    inline
    typename return_type<T_theta, T_lambda1, T_lambda2>::type
    log_mix(const T_theta& theta,
            const T_lambda1& lambda1,
            const T_lambda2& lambda2){
      using ::log;
      using stan::math::log_sum_exp;
      using stan::math::log1m;
      using stan::is_constant_struct;

      stan::error_handling::check_bounded("log_mix","theta",theta,0,1);
      stan::error_handling::check_not_nan("log_mix","lambda1",lambda1);
      stan::error_handling::check_not_nan("log_mix","lambda2",lambda2);

      OperandsAndPartials<T_theta, T_lambda1, T_lambda2>
        operands_and_partials(theta, lambda1, lambda2);

      double theta_double = value_of(theta);
      const double lambda1_double = value_of(lambda1);
      const double lambda2_double = value_of(lambda2);

      double log_mix_function_value
        = log_sum_exp(log(theta_double) + lambda1_double,
                         log1m(theta_double) + lambda2_double);

      double one_m_exp_lam2_m_lam1(0.0);
      double one_m_t_prod_exp_lam2_m_lam1(0.0);
      double one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1(0.0);

      if (lambda1 > lambda2)
        log_mix_deriv_inter_helper(theta_double,
                                   lambda1_double,
                                   lambda2_double,
                                   one_m_exp_lam2_m_lam1,
                                   one_m_t_prod_exp_lam2_m_lam1,
                                   one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1);
      else {
        log_mix_deriv_inter_helper(1.0 - theta_double,
                                   lambda2_double,
                                   lambda1_double,
                                   one_m_exp_lam2_m_lam1,
                                   one_m_t_prod_exp_lam2_m_lam1,
                                   one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1);
        one_m_exp_lam2_m_lam1 *= -1.0;
        theta_double = one_m_t_prod_exp_lam2_m_lam1;
        one_m_t_prod_exp_lam2_m_lam1 = value_of(1.0 - theta);
      }

      if (!is_constant_struct<T_theta>::value)
        operands_and_partials.d_x1[0]
          = one_m_exp_lam2_m_lam1
          * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
      if (!is_constant_struct<T_lambda1>::value)
        operands_and_partials.d_x2[0]
          = theta_double
          * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
      if (!is_constant_struct<T_lambda2>::value)
        operands_and_partials.d_x3[0]
          = one_m_t_prod_exp_lam2_m_lam1
          * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;

      return operands_and_partials.to_var(log_mix_function_value);
    }

  } // namespace agrad

} // namespace stan

#endif
<commit_msg>Minor change to lambda2 > lambda1 deriv calcs<commit_after>#ifndef STAN__AGRAD__REV__FUNCTIONS__LOG_MIX_HPP
#define STAN__AGRAD__REV__FUNCTIONS__LOG_MIX_HPP

#include <cmath>
#include <stan/agrad/rev.hpp>
#include <stan/error_handling/scalar/check_bounded.hpp>
#include <stan/error_handling/scalar/check_not_nan.hpp>
#include <stan/math/functions/log_sum_exp.hpp>
#include <stan/math/functions/log1m.hpp>
#include <stan/math/functions/value_of.hpp>
#include <stan/agrad/rev/functions/value_of.hpp>
#include <stan/meta/traits.hpp>
#include <stan/agrad/partials_vari.hpp>

namespace stan {

  namespace agrad {

    inline
    void log_mix_deriv_inter_helper(const double& theta_val,
                                    const double& lambda1_val,
                                    const double& lambda2_val,
                                    double& one_m_exp_lam2_m_lam1,
                                    double& one_m_t_prod_exp_lam2_m_lam1,
                                    double& one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1){
        using ::exp;
        double lam2_m_lam1 = lambda2_val - lambda1_val;
        double exp_lam2_m_lam1 = exp(lam2_m_lam1);
        one_m_exp_lam2_m_lam1 = 1 - exp_lam2_m_lam1;
        double one_m_t = 1 - theta_val;
        one_m_t_prod_exp_lam2_m_lam1 = one_m_t * exp_lam2_m_lam1;
        one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1
          = 1 / (theta_val + one_m_t_prod_exp_lam2_m_lam1);
    }

    template <typename T_theta,
              typename T_lambda1,
              typename T_lambda2>
    inline
    typename return_type<T_theta, T_lambda1, T_lambda2>::type
    log_mix(const T_theta& theta,
            const T_lambda1& lambda1,
            const T_lambda2& lambda2){
      using ::log;
      using stan::math::log_sum_exp;
      using stan::math::log1m;
      using stan::is_constant_struct;

      stan::error_handling::check_bounded("log_mix","theta",theta,0,1);
      stan::error_handling::check_not_nan("log_mix","lambda1",lambda1);
      stan::error_handling::check_not_nan("log_mix","lambda2",lambda2);

      OperandsAndPartials<T_theta, T_lambda1, T_lambda2>
        operands_and_partials(theta, lambda1, lambda2);

      double theta_double = value_of(theta);
      const double lambda1_double = value_of(lambda1);
      const double lambda2_double = value_of(lambda2);

      double log_mix_function_value
        = log_sum_exp(log(theta_double) + lambda1_double,
                         log1m(theta_double) + lambda2_double);

      double one_m_exp_lam2_m_lam1(0.0);
      double one_m_t_prod_exp_lam2_m_lam1(0.0);
      double one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1(0.0);

      if (lambda1 > lambda2)
        log_mix_deriv_inter_helper(theta_double,
                                   lambda1_double,
                                   lambda2_double,
                                   one_m_exp_lam2_m_lam1,
                                   one_m_t_prod_exp_lam2_m_lam1,
                                   one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1);
      else {
        log_mix_deriv_inter_helper(1.0 - theta_double,
                                   lambda2_double,
                                   lambda1_double,
                                   one_m_exp_lam2_m_lam1,
                                   one_m_t_prod_exp_lam2_m_lam1,
                                   one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1);
        one_m_exp_lam2_m_lam1 *= -1.0;
        theta_double = one_m_t_prod_exp_lam2_m_lam1;
        one_m_t_prod_exp_lam2_m_lam1 = 1.0 - value_of(theta);
      }

      if (!is_constant_struct<T_theta>::value)
        operands_and_partials.d_x1[0]
          = one_m_exp_lam2_m_lam1
          * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
      if (!is_constant_struct<T_lambda1>::value)
        operands_and_partials.d_x2[0]
          = theta_double
          * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
      if (!is_constant_struct<T_lambda2>::value)
        operands_and_partials.d_x3[0]
          = one_m_t_prod_exp_lam2_m_lam1
          * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;

      return operands_and_partials.to_var(log_mix_function_value);
    }

  } // namespace agrad

} // namespace stan

#endif
<|endoftext|>


<commit_before>#include "system/multirotor_vehicle_system.hpp"

MultirotorVehicleSystem::MultirotorVehicleSystem(Communicator& communicator)
  : VehicleSystem(communicator), MessageListener(communicator),
    mode(MultirotorControlMode::ANGULAR_POS) {
}

void MultirotorVehicleSystem::init() {
  // TODO: For now, arm the vehicle on initialization. In the future, this
  // should be removed and arming should be designated by a control input or
  // from a communication link.
}

void MultirotorVehicleSystem::update() {
  // Poll the gyroscope and accelerometer
  gyroscope_reading_t gyroReading = getGyroscope().readGyro();
  accelerometer_reading_t accelReading = getAccelerometer().readAccel();

  // Update the attitude estimate
  attitude_estimate_t estimate = getAttitudeEstimator().update(gyroReading, accelReading);

  // Poll for controller input
  controller_input_t input = getInputSource().read();

  // Run the controllers
  actuator_setpoint_t actuatorSp;
  if(isArmed()) {
    // Run the controller pipeline as determined by the subclass
    switch(mode) {
      case MultirotorControlMode::POSITION: {
        position_setpoint_t sp {
          .latitude_sp = input.roll_sp,
          .longitude_sp = input.pitch_sp,
          .yaw_pos_sp = input.yaw_sp,
          .altitude_sp = input.throttle_sp
        };
        actuatorSp = pipeline.run(estimate, sp, posController, attPosController, attVelController);
        break;
      }
      case MultirotorControlMode::VELOCITY: {
        // TODO: implement
        // actuatorSp = pipeline.run(estimate, sp, velController, attPosController, attVelController);
        break;
      }
      case MultirotorControlMode::ANGULAR_POS: {
        angular_position_setpoint_t sp {
          .roll_pos_sp = input.roll_sp,
          .pitch_pos_sp = input.pitch_sp,
          .yaw_pos_sp = input.yaw_sp,
          .throttle_sp = input.throttle_sp
        };
        actuatorSp = pipeline.run(estimate, sp, attPosController, attVelController);
        break;
      }
      case MultirotorControlMode::ANGULAR_RATE: {
        angular_velocity_setpoint_t sp {
          .roll_vel_sp = input.roll_sp,
          .pitch_vel_sp = input.pitch_sp,
          .yaw_vel_sp = input.yaw_sp,
          .throttle_sp = input.throttle_sp
        };
        actuatorSp = pipeline.run(estimate, sp, attVelController);
        break;
      }
    }
  } else {
    // Run the zero controller
    actuatorSp = zeroController.run(estimate, actuatorSp);
  }

  // Update motor outputs
  getMotorMapper().run(actuatorSp);
}

void MultirotorVehicleSystem::on(const protocol::message::set_arm_state_message_t& m) {
  setArmed(m.armed);
}
<commit_msg>Disarm multirotor by default.<commit_after>#include "system/multirotor_vehicle_system.hpp"

MultirotorVehicleSystem::MultirotorVehicleSystem(Communicator& communicator)
  : VehicleSystem(communicator), MessageListener(communicator),
    mode(MultirotorControlMode::ANGULAR_POS) {
  // Disarm by default. A set_arm_state_message_t message is required to enable
  // the control pipeline.
  setArmed(false);
}

void MultirotorVehicleSystem::init() {
}

void MultirotorVehicleSystem::update() {
  // Poll the gyroscope and accelerometer
  gyroscope_reading_t gyroReading = getGyroscope().readGyro();
  accelerometer_reading_t accelReading = getAccelerometer().readAccel();

  // Update the attitude estimate
  attitude_estimate_t estimate = getAttitudeEstimator().update(gyroReading, accelReading);

  // Poll for controller input
  controller_input_t input = getInputSource().read();

  // Run the controllers
  actuator_setpoint_t actuatorSp;
  if(isArmed()) {
    // Run the controller pipeline as determined by the subclass
    switch(mode) {
      case MultirotorControlMode::POSITION: {
        position_setpoint_t sp {
          .latitude_sp = input.roll_sp,
          .longitude_sp = input.pitch_sp,
          .yaw_pos_sp = input.yaw_sp,
          .altitude_sp = input.throttle_sp
        };
        actuatorSp = pipeline.run(estimate, sp, posController, attPosController, attVelController);
        break;
      }
      case MultirotorControlMode::VELOCITY: {
        // TODO: implement
        // actuatorSp = pipeline.run(estimate, sp, velController, attPosController, attVelController);
        break;
      }
      case MultirotorControlMode::ANGULAR_POS: {
        angular_position_setpoint_t sp {
          .roll_pos_sp = input.roll_sp,
          .pitch_pos_sp = input.pitch_sp,
          .yaw_pos_sp = input.yaw_sp,
          .throttle_sp = input.throttle_sp
        };
        actuatorSp = pipeline.run(estimate, sp, attPosController, attVelController);
        break;
      }
      case MultirotorControlMode::ANGULAR_RATE: {
        angular_velocity_setpoint_t sp {
          .roll_vel_sp = input.roll_sp,
          .pitch_vel_sp = input.pitch_sp,
          .yaw_vel_sp = input.yaw_sp,
          .throttle_sp = input.throttle_sp
        };
        actuatorSp = pipeline.run(estimate, sp, attVelController);
        break;
      }
    }
  } else {
    // Run the zero controller
    actuatorSp = zeroController.run(estimate, actuatorSp);
  }

  // Update motor outputs
  getMotorMapper().run(actuatorSp);
}

void MultirotorVehicleSystem::on(const protocol::message::set_arm_state_message_t& m) {
  setArmed(m.armed);
}
<|endoftext|>