<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef PCL_SIFT_KEYPOINT_IMPL_H_
#define PCL_SIFT_KEYPOINT_IMPL_H_

#include <pcl/keypoints/sift_keypoint.h>
#include <pcl/common/io.h>
#include <pcl/filters/voxel_grid.h>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::SIFTKeypoint<PointInT, PointOutT>::setScales (float min_scale, int nr_octaves, int nr_scales_per_octave)
{
  min_scale_ = min_scale;
  nr_octaves_ = nr_octaves;
  nr_scales_per_octave_ = nr_scales_per_octave;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::SIFTKeypoint<PointInT, PointOutT>::setMinimumContrast (float min_contrast)
{
  min_contrast_ = min_contrast;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> bool
pcl::SIFTKeypoint<PointInT, PointOutT>::initCompute ()
{
  if (min_scale_ <= 0)
  {
    PCL_ERROR ("[pcl::%s::initCompute] : Minimum scale (%f) must be strict positive!\n",
               name_.c_str (), min_scale_);
    return (false);
  }
  if (nr_octaves_ < 1)
  {
    PCL_ERROR ("[pcl::%s::initCompute] : Number of octaves (%d) must be at least 1!\n",
               name_.c_str (), nr_octaves_);
    return (false);
  }
  if (nr_scales_per_octave_ < 1)
  {
    PCL_ERROR ("[pcl::%s::initCompute] : Number of scales per octave (%d) must be at least 1!\n",
               name_.c_str (), nr_scales_per_octave_);
    return (false);
  }
  if (min_contrast_ < 0)
  {
    PCL_ERROR ("[pcl::%s::initCompute] : Minimum contrast (%f) must be non-negative!\n",
               name_.c_str (), min_contrast_);
    return (false);
  }

  this->setKSearch (1);
  tree_.reset (new pcl::search::KdTree<PointInT> (true));
  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::SIFTKeypoint<PointInT, PointOutT>::detectKeypoints (PointCloudOut &output)
{
  if (surface_ != input_)
  {
    PCL_WARN ("[pcl::%s::detectKeypoints] : ", name_.c_str ());
    PCL_WARN ("A search surface has been set by setSearchSurface, but this SIFT keypoint detection algorithm does ");
    PCL_WARN ("not support search surfaces other than the input cloud.  ");
    PCL_WARN ("The cloud provided in setInputCloud is being used instead.\n");
  }

  // Check if the output has a "scale" field
  scale_idx_ = pcl::getFieldIndex<PointOutT> (output, "scale", out_fields_);

  // Make sure the output cloud is empty
  output.points.clear ();

  // Create a local copy of the input cloud that will be resized for each octave
  boost::shared_ptr<pcl::PointCloud<PointInT> > cloud (new pcl::PointCloud<PointInT> (*input_));

  VoxelGrid<PointInT> voxel_grid;
  // Search for keypoints at each octave
  float scale = min_scale_;
  for (int i_octave = 0; i_octave < nr_octaves_; ++i_octave)
  {
    // Downsample the point cloud
    const float s = 1.0f * scale; // note: this can be adjusted
    voxel_grid.setLeafSize (s, s, s);
    voxel_grid.setInputCloud (cloud);
    boost::shared_ptr<pcl::PointCloud<PointInT> > temp (new pcl::PointCloud<PointInT>);
    voxel_grid.filter (*temp);
    cloud = temp;

    // Make sure the downsampled cloud still has enough points
    const size_t min_nr_points = 25;
    if (cloud->points.size () < min_nr_points)
      break;

    // Update the KdTree with the downsampled points
    tree_->setInputCloud (cloud);

    // Detect keypoints for the current scale
    detectKeypointsForOctave (*cloud, *tree_, scale, nr_scales_per_octave_, output);

    // Increase the scale by another octave
    scale *= 2;
  }

  output.height = 1;
  output.width = static_cast<uint32_t> (output.points.size ());
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::SIFTKeypoint<PointInT, PointOutT>::detectKeypointsForOctave (
    const PointCloudIn &input, KdTree &tree, float base_scale, int nr_scales_per_octave,
    PointCloudOut &output)
{
  // Compute the difference of Gaussians (DoG) scale space
  std::vector<float> scales (nr_scales_per_octave + 3);
  for (int i_scale = 0; i_scale <= nr_scales_per_octave + 2; ++i_scale)
  {
    scales[i_scale] = base_scale * powf (2.0f, (1.0f * static_cast<float> (i_scale) - 1.0f) / static_cast<float> (nr_scales_per_octave));
  }
  Eigen::MatrixXf diff_of_gauss;
  computeScaleSpace (input, tree, scales, diff_of_gauss);

  // Find extrema in the DoG scale space
  std::vector<int> extrema_indices, extrema_scales;
  findScaleSpaceExtrema (input, tree, diff_of_gauss, extrema_indices, extrema_scales);

  output.points.reserve (output.points.size () + extrema_indices.size ());
  // Save scale?
  if (scale_idx_ != -1)
  {
    // Add keypoints to output
    for (size_t i_keypoint = 0; i_keypoint < extrema_indices.size (); ++i_keypoint)
    {
      PointOutT keypoint;
      const int &keypoint_index = extrema_indices[i_keypoint];

      keypoint.x = input.points[keypoint_index].x;
      keypoint.y = input.points[keypoint_index].y;
      keypoint.z = input.points[keypoint_index].z;
      memcpy (reinterpret_cast<char*> (&keypoint) + out_fields_[scale_idx_].offset,
              &scales[extrema_scales[i_keypoint]], sizeof (float));
      output.points.push_back (keypoint);
    }
  }
  else
  {
    // Add keypoints to output
    for (size_t i_keypoint = 0; i_keypoint < extrema_indices.size (); ++i_keypoint)
    {
      PointOutT keypoint;
      const int &keypoint_index = extrema_indices[i_keypoint];

      keypoint.x = input.points[keypoint_index].x;
      keypoint.y = input.points[keypoint_index].y;
      keypoint.z = input.points[keypoint_index].z;

      output.points.push_back (keypoint);
    }
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT>
void pcl::SIFTKeypoint<PointInT, PointOutT>::computeScaleSpace (
    const PointCloudIn &input, KdTree &tree, const std::vector<float> &scales,
    Eigen::MatrixXf &diff_of_gauss)
{
  diff_of_gauss.resize (input.size (), scales.size () - 1);

  // For efficiency, we will only filter over points within 3 standard deviations
  const float max_radius = 3.0f * scales.back ();

  for (int i_point = 0; i_point < static_cast<int> (input.size ()); ++i_point)
  {
    std::vector<int> nn_indices;
    std::vector<float> nn_dist;
    tree.radiusSearch (i_point, max_radius, nn_indices, nn_dist); // *
    // * note: at this stage of the algorithm, we must find all points within a radius defined by the maximum scale,
    //   regardless of the configurable search method specified by the user, so we directly employ tree.radiusSearch
    //   here instead of using searchForNeighbors.

    // For each scale, compute the Gaussian "filter response" at the current point
    float filter_response = 0.0f;
    float previous_filter_response;
    for (size_t i_scale = 0; i_scale < scales.size (); ++i_scale)
    {
      float sigma_sqr = powf (scales[i_scale], 2.0f);

      float numerator = 0.0f;
      float denominator = 0.0f;
      for (size_t i_neighbor = 0; i_neighbor < nn_indices.size (); ++i_neighbor)
      {
        const float &value = getFieldValue_ (input.points[nn_indices[i_neighbor]]);
        const float &dist_sqr = nn_dist[i_neighbor];
        if (dist_sqr <= 9*sigma_sqr)
        {
          float w = expf (-0.5f * dist_sqr / sigma_sqr);
          numerator += value * w;
          denominator += w;
        }
        else break; // i.e. if dist > 3 standard deviations, then terminate early
      }
      previous_filter_response = filter_response;
      filter_response = numerator / denominator;

      // Compute the difference between adjacent scales
      if (i_scale > 0)
        diff_of_gauss (i_point, i_scale - 1) = filter_response - previous_filter_response;
    }
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::SIFTKeypoint<PointInT, PointOutT>::findScaleSpaceExtrema (
    const PointCloudIn &input, KdTree &tree, const Eigen::MatrixXf &diff_of_gauss,
    std::vector<int> &extrema_indices, std::vector<int> &extrema_scales)
{
  const int k = 25;
  std::vector<int> nn_indices (k);
  std::vector<float> nn_dist (k);

  const int nr_scales = static_cast<int> (diff_of_gauss.cols ());
  std::vector<float> min_val (nr_scales), max_val (nr_scales);

  for (int i_point = 0; i_point < static_cast<int> (input.size ()); ++i_point)
  {
    // Define the local neighborhood around the current point
    const size_t nr_nn = tree.nearestKSearch (i_point, k, nn_indices, nn_dist); //*
    // * note: the neighborhood for finding local extrema is best defined as a small fixed-k neighborhood, regardless of
    //   the configurable search method specified by the user, so we directly employ tree.nearestKSearch here instead
    //   of using searchForNeighbors

    // At each scale, find the extreme values of the DoG within the current neighborhood
    for (int i_scale = 0; i_scale < nr_scales; ++i_scale)
    {
      min_val[i_scale] = std::numeric_limits<float>::max ();
      max_val[i_scale] = -std::numeric_limits<float>::max ();

      for (size_t i_neighbor = 0; i_neighbor < nr_nn; ++i_neighbor)
      {
        const float &d = diff_of_gauss (nn_indices[i_neighbor], i_scale);

        min_val[i_scale] = (std::min) (min_val[i_scale], d);
        max_val[i_scale] = (std::max) (max_val[i_scale], d);
      }
    }

    // If the current point is an extreme value with high enough contrast, add it as a keypoint
    for (int i_scale = 1; i_scale < nr_scales - 1; ++i_scale)
    {
      const float &val = diff_of_gauss (i_point, i_scale);

      // Does the point have sufficient contrast?
      if (fabs (val) >= min_contrast_)
      {
        // Is it a local minimum?
        if ((val == min_val[i_scale]) &&
            (val <  min_val[i_scale - 1]) &&
            (val <  min_val[i_scale + 1]))
        {
          extrema_indices.push_back (i_point);
          extrema_scales.push_back (i_scale);
        }
        // Is it a local maximum?
        else if ((val == max_val[i_scale]) &&
                 (val >  max_val[i_scale - 1]) &&
                 (val >  max_val[i_scale + 1]))
        {
          extrema_indices.push_back (i_point);
          extrema_scales.push_back (i_scale);
        }
      }
    }
  }
}

#define PCL_INSTANTIATE_SIFTKeypoint(T,U) template class PCL_EXPORTS pcl::SIFTKeypoint<T,U>;

#endif // #ifndef PCL_SIFT_KEYPOINT_IMPL_H_

<commit_msg>* fixed issue #809: fix SIFT surface_ warning (thanks Christian)<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef PCL_SIFT_KEYPOINT_IMPL_H_
#define PCL_SIFT_KEYPOINT_IMPL_H_

#include <pcl/keypoints/sift_keypoint.h>
#include <pcl/common/io.h>
#include <pcl/filters/voxel_grid.h>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::SIFTKeypoint<PointInT, PointOutT>::setScales (float min_scale, int nr_octaves, int nr_scales_per_octave)
{
  min_scale_ = min_scale;
  nr_octaves_ = nr_octaves;
  nr_scales_per_octave_ = nr_scales_per_octave;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::SIFTKeypoint<PointInT, PointOutT>::setMinimumContrast (float min_contrast)
{
  min_contrast_ = min_contrast;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> bool
pcl::SIFTKeypoint<PointInT, PointOutT>::initCompute ()
{
  if (min_scale_ <= 0)
  {
    PCL_ERROR ("[pcl::%s::initCompute] : Minimum scale (%f) must be strict positive!\n",
               name_.c_str (), min_scale_);
    return (false);
  }
  if (nr_octaves_ < 1)
  {
    PCL_ERROR ("[pcl::%s::initCompute] : Number of octaves (%d) must be at least 1!\n",
               name_.c_str (), nr_octaves_);
    return (false);
  }
  if (nr_scales_per_octave_ < 1)
  {
    PCL_ERROR ("[pcl::%s::initCompute] : Number of scales per octave (%d) must be at least 1!\n",
               name_.c_str (), nr_scales_per_octave_);
    return (false);
  }
  if (min_contrast_ < 0)
  {
    PCL_ERROR ("[pcl::%s::initCompute] : Minimum contrast (%f) must be non-negative!\n",
               name_.c_str (), min_contrast_);
    return (false);
  }

  this->setKSearch (1);
  tree_.reset (new pcl::search::KdTree<PointInT> (true));
  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::SIFTKeypoint<PointInT, PointOutT>::detectKeypoints (PointCloudOut &output)
{
  if (surface_ && surface_ != input_)
  {
    PCL_WARN ("[pcl::%s::detectKeypoints] : ", name_.c_str ());
    PCL_WARN ("A search surface has been set by setSearchSurface, but this SIFT keypoint detection algorithm does ");
    PCL_WARN ("not support search surfaces other than the input cloud.  ");
    PCL_WARN ("The cloud provided in setInputCloud is being used instead.\n");
  }

  // Check if the output has a "scale" field
  scale_idx_ = pcl::getFieldIndex<PointOutT> (output, "scale", out_fields_);

  // Make sure the output cloud is empty
  output.points.clear ();

  // Create a local copy of the input cloud that will be resized for each octave
  boost::shared_ptr<pcl::PointCloud<PointInT> > cloud (new pcl::PointCloud<PointInT> (*input_));

  VoxelGrid<PointInT> voxel_grid;
  // Search for keypoints at each octave
  float scale = min_scale_;
  for (int i_octave = 0; i_octave < nr_octaves_; ++i_octave)
  {
    // Downsample the point cloud
    const float s = 1.0f * scale; // note: this can be adjusted
    voxel_grid.setLeafSize (s, s, s);
    voxel_grid.setInputCloud (cloud);
    boost::shared_ptr<pcl::PointCloud<PointInT> > temp (new pcl::PointCloud<PointInT>);
    voxel_grid.filter (*temp);
    cloud = temp;

    // Make sure the downsampled cloud still has enough points
    const size_t min_nr_points = 25;
    if (cloud->points.size () < min_nr_points)
      break;

    // Update the KdTree with the downsampled points
    tree_->setInputCloud (cloud);

    // Detect keypoints for the current scale
    detectKeypointsForOctave (*cloud, *tree_, scale, nr_scales_per_octave_, output);

    // Increase the scale by another octave
    scale *= 2;
  }

  output.height = 1;
  output.width = static_cast<uint32_t> (output.points.size ());
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::SIFTKeypoint<PointInT, PointOutT>::detectKeypointsForOctave (
    const PointCloudIn &input, KdTree &tree, float base_scale, int nr_scales_per_octave,
    PointCloudOut &output)
{
  // Compute the difference of Gaussians (DoG) scale space
  std::vector<float> scales (nr_scales_per_octave + 3);
  for (int i_scale = 0; i_scale <= nr_scales_per_octave + 2; ++i_scale)
  {
    scales[i_scale] = base_scale * powf (2.0f, (1.0f * static_cast<float> (i_scale) - 1.0f) / static_cast<float> (nr_scales_per_octave));
  }
  Eigen::MatrixXf diff_of_gauss;
  computeScaleSpace (input, tree, scales, diff_of_gauss);

  // Find extrema in the DoG scale space
  std::vector<int> extrema_indices, extrema_scales;
  findScaleSpaceExtrema (input, tree, diff_of_gauss, extrema_indices, extrema_scales);

  output.points.reserve (output.points.size () + extrema_indices.size ());
  // Save scale?
  if (scale_idx_ != -1)
  {
    // Add keypoints to output
    for (size_t i_keypoint = 0; i_keypoint < extrema_indices.size (); ++i_keypoint)
    {
      PointOutT keypoint;
      const int &keypoint_index = extrema_indices[i_keypoint];

      keypoint.x = input.points[keypoint_index].x;
      keypoint.y = input.points[keypoint_index].y;
      keypoint.z = input.points[keypoint_index].z;
      memcpy (reinterpret_cast<char*> (&keypoint) + out_fields_[scale_idx_].offset,
              &scales[extrema_scales[i_keypoint]], sizeof (float));
      output.points.push_back (keypoint);
    }
  }
  else
  {
    // Add keypoints to output
    for (size_t i_keypoint = 0; i_keypoint < extrema_indices.size (); ++i_keypoint)
    {
      PointOutT keypoint;
      const int &keypoint_index = extrema_indices[i_keypoint];

      keypoint.x = input.points[keypoint_index].x;
      keypoint.y = input.points[keypoint_index].y;
      keypoint.z = input.points[keypoint_index].z;

      output.points.push_back (keypoint);
    }
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT>
void pcl::SIFTKeypoint<PointInT, PointOutT>::computeScaleSpace (
    const PointCloudIn &input, KdTree &tree, const std::vector<float> &scales,
    Eigen::MatrixXf &diff_of_gauss)
{
  diff_of_gauss.resize (input.size (), scales.size () - 1);

  // For efficiency, we will only filter over points within 3 standard deviations
  const float max_radius = 3.0f * scales.back ();

  for (int i_point = 0; i_point < static_cast<int> (input.size ()); ++i_point)
  {
    std::vector<int> nn_indices;
    std::vector<float> nn_dist;
    tree.radiusSearch (i_point, max_radius, nn_indices, nn_dist); // *
    // * note: at this stage of the algorithm, we must find all points within a radius defined by the maximum scale,
    //   regardless of the configurable search method specified by the user, so we directly employ tree.radiusSearch
    //   here instead of using searchForNeighbors.

    // For each scale, compute the Gaussian "filter response" at the current point
    float filter_response = 0.0f;
    float previous_filter_response;
    for (size_t i_scale = 0; i_scale < scales.size (); ++i_scale)
    {
      float sigma_sqr = powf (scales[i_scale], 2.0f);

      float numerator = 0.0f;
      float denominator = 0.0f;
      for (size_t i_neighbor = 0; i_neighbor < nn_indices.size (); ++i_neighbor)
      {
        const float &value = getFieldValue_ (input.points[nn_indices[i_neighbor]]);
        const float &dist_sqr = nn_dist[i_neighbor];
        if (dist_sqr <= 9*sigma_sqr)
        {
          float w = expf (-0.5f * dist_sqr / sigma_sqr);
          numerator += value * w;
          denominator += w;
        }
        else break; // i.e. if dist > 3 standard deviations, then terminate early
      }
      previous_filter_response = filter_response;
      filter_response = numerator / denominator;

      // Compute the difference between adjacent scales
      if (i_scale > 0)
        diff_of_gauss (i_point, i_scale - 1) = filter_response - previous_filter_response;
    }
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::SIFTKeypoint<PointInT, PointOutT>::findScaleSpaceExtrema (
    const PointCloudIn &input, KdTree &tree, const Eigen::MatrixXf &diff_of_gauss,
    std::vector<int> &extrema_indices, std::vector<int> &extrema_scales)
{
  const int k = 25;
  std::vector<int> nn_indices (k);
  std::vector<float> nn_dist (k);

  const int nr_scales = static_cast<int> (diff_of_gauss.cols ());
  std::vector<float> min_val (nr_scales), max_val (nr_scales);

  for (int i_point = 0; i_point < static_cast<int> (input.size ()); ++i_point)
  {
    // Define the local neighborhood around the current point
    const size_t nr_nn = tree.nearestKSearch (i_point, k, nn_indices, nn_dist); //*
    // * note: the neighborhood for finding local extrema is best defined as a small fixed-k neighborhood, regardless of
    //   the configurable search method specified by the user, so we directly employ tree.nearestKSearch here instead
    //   of using searchForNeighbors

    // At each scale, find the extreme values of the DoG within the current neighborhood
    for (int i_scale = 0; i_scale < nr_scales; ++i_scale)
    {
      min_val[i_scale] = std::numeric_limits<float>::max ();
      max_val[i_scale] = -std::numeric_limits<float>::max ();

      for (size_t i_neighbor = 0; i_neighbor < nr_nn; ++i_neighbor)
      {
        const float &d = diff_of_gauss (nn_indices[i_neighbor], i_scale);

        min_val[i_scale] = (std::min) (min_val[i_scale], d);
        max_val[i_scale] = (std::max) (max_val[i_scale], d);
      }
    }

    // If the current point is an extreme value with high enough contrast, add it as a keypoint
    for (int i_scale = 1; i_scale < nr_scales - 1; ++i_scale)
    {
      const float &val = diff_of_gauss (i_point, i_scale);

      // Does the point have sufficient contrast?
      if (fabs (val) >= min_contrast_)
      {
        // Is it a local minimum?
        if ((val == min_val[i_scale]) &&
            (val <  min_val[i_scale - 1]) &&
            (val <  min_val[i_scale + 1]))
        {
          extrema_indices.push_back (i_point);
          extrema_scales.push_back (i_scale);
        }
        // Is it a local maximum?
        else if ((val == max_val[i_scale]) &&
                 (val >  max_val[i_scale - 1]) &&
                 (val >  max_val[i_scale + 1]))
        {
          extrema_indices.push_back (i_point);
          extrema_scales.push_back (i_scale);
        }
      }
    }
  }
}

#define PCL_INSTANTIATE_SIFTKeypoint(T,U) template class PCL_EXPORTS pcl::SIFTKeypoint<T,U>;

#endif // #ifndef PCL_SIFT_KEYPOINT_IMPL_H_

<|endoftext|>


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

    strncpy( m_pcFile , pcFile, 1024 );
    printf("file generated=%s\n", m_pcFile);
    m_f = fopen( m_pcFile , "w" );
    strcpy(theLocale, locale);
}

OFileWriter::~OFileWriter() {
    if(m_f)
        fclose( m_f );
}

void OFileWriter::writeInt(sal_Int16 nb) const
{
    fprintf(m_f, "%d", nb);
}

void OFileWriter::writeAsciiString(const char* str) const
{
    fprintf(m_f, "%s", str);
}

void OFileWriter::writeStringCharacters(const ::rtl::OUString& str) const
{
    for(int i = 0; i < str.getLength(); i++)
        fprintf(m_f, "0x%x, ", str[i]);
}

void OFileWriter::writeFunction(const char *func, const char *count, const char *array) const
{
    fprintf(m_f, "sal_Unicode **  SAL_CALL %s%s(sal_Int16& count)\n{\n", func, theLocale);
    fprintf(m_f, "\tcount = %s;\n", count);
    fprintf(m_f, "\treturn (sal_Unicode**)%s;\n}\n", array);
}

void OFileWriter::writeRefFunction(const char *func, const ::rtl::OUString& useLocale) const
{
    const char* locale = OUStringToOString(useLocale, RTL_TEXTENCODING_ASCII_US).getStr();
    fprintf(m_f, "extern sal_Unicode **  SAL_CALL %s%s(sal_Int16& count);\n", func, locale);
    fprintf(m_f, "sal_Unicode **  SAL_CALL %s%s(sal_Int16& count)\n{\n", func, theLocale);
    fprintf(m_f, "\treturn %s%s(count);\n}\n", func, locale);
}

void OFileWriter::writeFunction(const char *func, const char *count, const char *array, const char *from, const char *to) const
{
    fprintf(m_f, "sal_Unicode **  SAL_CALL %s%s(sal_Int16& count, const sal_Unicode*& from, const sal_Unicode*& to)\n{\n", func, theLocale);
    fprintf(m_f, "\tcount = %s;\n", count);
    fprintf(m_f, "\tfrom = %s;\n", from);
    fprintf(m_f, "\tto = %s;\n", to);
    fprintf(m_f, "\treturn (sal_Unicode**)%s;\n}\n", array);
}

void OFileWriter::writeRefFunction(const char *func, const ::rtl::OUString& useLocale, const char *to) const
{
    const char* locale = OUStringToOString(useLocale, RTL_TEXTENCODING_ASCII_US).getStr();
    fprintf(m_f, "extern sal_Unicode **  SAL_CALL %s%s(sal_Int16& count, const sal_Unicode*& from, const sal_Unicode*& to);\n", func, locale);
    fprintf(m_f, "sal_Unicode **  SAL_CALL %s%s(sal_Int16& count, const sal_Unicode*& from, const sal_Unicode*& to)\n{\n", func, theLocale);
    fprintf(m_f, "\tto = %s;\n", to);
    fprintf(m_f, "\tconst sal_Unicode* tmp;\n");
    fprintf(m_f, "\treturn %s%s(count, from, tmp);\n}\n", func, locale);
}

void OFileWriter::writeFunction2(const char *func, const char *style, const char* attr, const char *array) const
{
    fprintf(m_f, "const sal_Unicode ***  SAL_CALL %s%s( sal_Int16& nStyles, sal_Int16& nAttributes )\n{\n", func, theLocale);
    fprintf(m_f, "\tnStyles     = %s;\n", style);
    fprintf(m_f, "\tnAttributes = %s;\n", attr);
    fprintf(m_f, "\treturn %s;\n}\n", array);
}

void OFileWriter::writeRefFunction2(const char *func, const ::rtl::OUString& useLocale) const
{
    const char* locale = OUStringToOString(useLocale, RTL_TEXTENCODING_ASCII_US).getStr();
    fprintf(m_f, "extern const sal_Unicode ***  SAL_CALL %s%s(sal_Int16& nStyles, sal_Int16& nAttributes);\n", func, locale);
    fprintf(m_f, "const sal_Unicode ***  SAL_CALL %s%s(sal_Int16& nStyles, sal_Int16& nAttributes)\n{\n", func, theLocale);
    fprintf(m_f, "\treturn %s%s(nStyles, nAttributes);\n}\n", func, locale);
}

void OFileWriter::writeFunction3(const char *func, const char *style, const char* levels, const char* attr, const char *array) const
{
    fprintf(m_f, "const sal_Unicode ****  SAL_CALL %s%s( sal_Int16& nStyles, sal_Int16& nLevels, sal_Int16& nAttributes )\n{\n", func, theLocale);
    fprintf(m_f, "\tnStyles     = %s;\n", style);
    fprintf(m_f, "\tnLevels     = %s;\n", levels);
    fprintf(m_f, "\tnAttributes = %s;\n", attr);
    fprintf(m_f, "\treturn %s;\n}\n", array);
}

void OFileWriter::writeRefFunction3(const char *func, const ::rtl::OUString& useLocale) const
{
    const char* locale = OUStringToOString(useLocale, RTL_TEXTENCODING_ASCII_US).getStr();
    fprintf(m_f, "extern const sal_Unicode ****  SAL_CALL %s%s(sal_Int16& nStyles, sal_Int16& nLevels, sal_Int16& nAttributes);\n", func, locale);
    fprintf(m_f, "const sal_Unicode ****  SAL_CALL %s%s(sal_Int16& nStyles, sal_Int16& nLevels, sal_Int16& nAttributes)\n{\n", func, theLocale);
    fprintf(m_f, "\treturn %s%s(nStyles, nLevels, nAttributes);\n}\n", func, locale);
}

void OFileWriter::writeIntParameter(const sal_Char* pAsciiStr, const sal_Int16 count, sal_Int16 val) const
{
    fprintf(m_f, "static const sal_Unicode %s%d[] = {%d};\n", pAsciiStr, count, val);
}

void OFileWriter::writeDefaultParameter(const sal_Char* pAsciiStr, const ::rtl::OUString& str, sal_Int16 count) const
{
    fprintf(m_f,"static const sal_Unicode default%s%d[] = {%d};\n", pAsciiStr, count,
        str.equalsAscii("true") ? 1 : 0);
}

void OFileWriter::writeDefaultParameter(const sal_Char* pAsciiStr, const ::rtl::OUString& str) const
{
    fprintf(m_f,"static const sal_Unicode default%s[] = {%d};\n", pAsciiStr,
        str.equalsAscii("true") ? 1 : 0);
}

void OFileWriter::writeParameter(const sal_Char* pAsciiStr, const ::rtl::OUString& aChars) const
{
    fprintf(m_f, "static const sal_Unicode %s[] = {", pAsciiStr);
    writeStringCharacters(aChars);
    fprintf(m_f, "0x0};\n");
}

void OFileWriter::writeParameter(const sal_Char* pAsciiStr, const ::rtl::OUString& aChars, sal_Int16 count) const
{
    fprintf(m_f, "static const sal_Unicode %s%d[] = {", pAsciiStr, count);
    writeStringCharacters(aChars);
    fprintf(m_f, "0x0};\n");
}

void OFileWriter::writeParameter(const sal_Char* pAsciiStr, const ::rtl::OUString& aChars, sal_Int16 count0, sal_Int16 count1) const
{
    fprintf(m_f, "static const sal_Unicode %s%d%d[] = {", pAsciiStr, count0, count1);
    writeStringCharacters(aChars);
    fprintf(m_f, "0x0};\n");
}

void OFileWriter::writeParameter(const sal_Char* pTagStr, const sal_Char* pAsciiStr, const ::rtl::OUString& aChars, const sal_Int16 count) const
{
    fprintf(m_f, "static const sal_Unicode %s%s%d[] = {", pTagStr, pAsciiStr, count);
    writeStringCharacters(aChars);
    fprintf(m_f, "0x0};\n");
}

void OFileWriter::writeParameter(const sal_Char* pTagStr, const sal_Char* pAsciiStr, const ::rtl::OUString& aChars) const
{
    fprintf(m_f, "static const sal_Unicode %s%s[] = {", pTagStr, pAsciiStr);
    writeStringCharacters(aChars);
    fprintf(m_f, "0x0};\n");
}

void OFileWriter::writeParameter(const sal_Char* pTagStr, const sal_Char* pAsciiStr, const ::rtl::OUString& aChars, sal_Int16 count0, sal_Int16 count1) const
{
    fprintf(m_f, "static const sal_Unicode %s%s%d%d[] = {", pTagStr, pAsciiStr, count0, count1);
    writeStringCharacters(aChars);
    fprintf(m_f, "0x0};\n");
}

void OFileWriter::flush(void) const
{
    fflush( m_f );
}

void OFileWriter::closeOutput(void) const
{
    if(m_f)
    {
        fclose( m_f );
        const_cast< OFileWriter * > ( this )->m_f = 0;
    }
}

<commit_msg>#101191# don't remember pointers to buffers of temporary objects, they may be gone any time<commit_after>/*************************************************************************
 *
 *  $RCSfile: filewriter.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: er $ $Date: 2002-07-15 14:16:10 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include <stdio.h>
#include <string.h>
#include "LocaleNode.hxx"
//-----------------------------------------
// The document handler, which is needed for the saxparser
// The Documenthandler for reading sax
//-----------------------------------------
OFileWriter::OFileWriter(const char *pcFile, const char *locale ) {

    strncpy( m_pcFile , pcFile, 1024 );
    printf("file generated=%s\n", m_pcFile);
    m_f = fopen( m_pcFile , "w" );
    strcpy(theLocale, locale);
}

OFileWriter::~OFileWriter() {
    if(m_f)
        fclose( m_f );
}

void OFileWriter::writeInt(sal_Int16 nb) const
{
    fprintf(m_f, "%d", nb);
}

void OFileWriter::writeAsciiString(const char* str) const
{
    fprintf(m_f, "%s", str);
}

void OFileWriter::writeStringCharacters(const ::rtl::OUString& str) const
{
    for(int i = 0; i < str.getLength(); i++)
        fprintf(m_f, "0x%x, ", str[i]);
}

void OFileWriter::writeFunction(const char *func, const char *count, const char *array) const
{
    fprintf(m_f, "sal_Unicode **  SAL_CALL %s%s(sal_Int16& count)\n{\n", func, theLocale);
    fprintf(m_f, "\tcount = %s;\n", count);
    fprintf(m_f, "\treturn (sal_Unicode**)%s;\n}\n", array);
}

void OFileWriter::writeRefFunction(const char *func, const ::rtl::OUString& useLocale) const
{
    OString aRefLocale( OUStringToOString(useLocale, RTL_TEXTENCODING_ASCII_US) );
    const char* locale = aRefLocale.getStr();
    fprintf(m_f, "extern sal_Unicode **  SAL_CALL %s%s(sal_Int16& count);\n", func, locale);
    fprintf(m_f, "sal_Unicode **  SAL_CALL %s%s(sal_Int16& count)\n{\n", func, theLocale);
    fprintf(m_f, "\treturn %s%s(count);\n}\n", func, locale);
}

void OFileWriter::writeFunction(const char *func, const char *count, const char *array, const char *from, const char *to) const
{
    fprintf(m_f, "sal_Unicode **  SAL_CALL %s%s(sal_Int16& count, const sal_Unicode*& from, const sal_Unicode*& to)\n{\n", func, theLocale);
    fprintf(m_f, "\tcount = %s;\n", count);
    fprintf(m_f, "\tfrom = %s;\n", from);
    fprintf(m_f, "\tto = %s;\n", to);
    fprintf(m_f, "\treturn (sal_Unicode**)%s;\n}\n", array);
}

void OFileWriter::writeRefFunction(const char *func, const ::rtl::OUString& useLocale, const char *to) const
{
    OString aRefLocale( OUStringToOString(useLocale, RTL_TEXTENCODING_ASCII_US) );
    const char* locale = aRefLocale.getStr();
    fprintf(m_f, "extern sal_Unicode **  SAL_CALL %s%s(sal_Int16& count, const sal_Unicode*& from, const sal_Unicode*& to);\n", func, locale);
    fprintf(m_f, "sal_Unicode **  SAL_CALL %s%s(sal_Int16& count, const sal_Unicode*& from, const sal_Unicode*& to)\n{\n", func, theLocale);
    fprintf(m_f, "\tto = %s;\n", to);
    fprintf(m_f, "\tconst sal_Unicode* tmp;\n");
    fprintf(m_f, "\treturn %s%s(count, from, tmp);\n}\n", func, locale);
}

void OFileWriter::writeFunction2(const char *func, const char *style, const char* attr, const char *array) const
{
    fprintf(m_f, "const sal_Unicode ***  SAL_CALL %s%s( sal_Int16& nStyles, sal_Int16& nAttributes )\n{\n", func, theLocale);
    fprintf(m_f, "\tnStyles     = %s;\n", style);
    fprintf(m_f, "\tnAttributes = %s;\n", attr);
    fprintf(m_f, "\treturn %s;\n}\n", array);
}

void OFileWriter::writeRefFunction2(const char *func, const ::rtl::OUString& useLocale) const
{
    OString aRefLocale( OUStringToOString(useLocale, RTL_TEXTENCODING_ASCII_US) );
    const char* locale = aRefLocale.getStr();
    fprintf(m_f, "extern const sal_Unicode ***  SAL_CALL %s%s(sal_Int16& nStyles, sal_Int16& nAttributes);\n", func, locale);
    fprintf(m_f, "const sal_Unicode ***  SAL_CALL %s%s(sal_Int16& nStyles, sal_Int16& nAttributes)\n{\n", func, theLocale);
    fprintf(m_f, "\treturn %s%s(nStyles, nAttributes);\n}\n", func, locale);
}

void OFileWriter::writeFunction3(const char *func, const char *style, const char* levels, const char* attr, const char *array) const
{
    fprintf(m_f, "const sal_Unicode ****  SAL_CALL %s%s( sal_Int16& nStyles, sal_Int16& nLevels, sal_Int16& nAttributes )\n{\n", func, theLocale);
    fprintf(m_f, "\tnStyles     = %s;\n", style);
    fprintf(m_f, "\tnLevels     = %s;\n", levels);
    fprintf(m_f, "\tnAttributes = %s;\n", attr);
    fprintf(m_f, "\treturn %s;\n}\n", array);
}

void OFileWriter::writeRefFunction3(const char *func, const ::rtl::OUString& useLocale) const
{
    OString aRefLocale( OUStringToOString(useLocale, RTL_TEXTENCODING_ASCII_US) );
    const char* locale = aRefLocale.getStr();
    fprintf(m_f, "extern const sal_Unicode ****  SAL_CALL %s%s(sal_Int16& nStyles, sal_Int16& nLevels, sal_Int16& nAttributes);\n", func, locale);
    fprintf(m_f, "const sal_Unicode ****  SAL_CALL %s%s(sal_Int16& nStyles, sal_Int16& nLevels, sal_Int16& nAttributes)\n{\n", func, theLocale);
    fprintf(m_f, "\treturn %s%s(nStyles, nLevels, nAttributes);\n}\n", func, locale);
}

void OFileWriter::writeIntParameter(const sal_Char* pAsciiStr, const sal_Int16 count, sal_Int16 val) const
{
    fprintf(m_f, "static const sal_Unicode %s%d[] = {%d};\n", pAsciiStr, count, val);
}

void OFileWriter::writeDefaultParameter(const sal_Char* pAsciiStr, const ::rtl::OUString& str, sal_Int16 count) const
{
    fprintf(m_f,"static const sal_Unicode default%s%d[] = {%d};\n", pAsciiStr, count,
        str.equalsAscii("true") ? 1 : 0);
}

void OFileWriter::writeDefaultParameter(const sal_Char* pAsciiStr, const ::rtl::OUString& str) const
{
    fprintf(m_f,"static const sal_Unicode default%s[] = {%d};\n", pAsciiStr,
        str.equalsAscii("true") ? 1 : 0);
}

void OFileWriter::writeParameter(const sal_Char* pAsciiStr, const ::rtl::OUString& aChars) const
{
    fprintf(m_f, "static const sal_Unicode %s[] = {", pAsciiStr);
    writeStringCharacters(aChars);
    fprintf(m_f, "0x0};\n");
}

void OFileWriter::writeParameter(const sal_Char* pAsciiStr, const ::rtl::OUString& aChars, sal_Int16 count) const
{
    fprintf(m_f, "static const sal_Unicode %s%d[] = {", pAsciiStr, count);
    writeStringCharacters(aChars);
    fprintf(m_f, "0x0};\n");
}

void OFileWriter::writeParameter(const sal_Char* pAsciiStr, const ::rtl::OUString& aChars, sal_Int16 count0, sal_Int16 count1) const
{
    fprintf(m_f, "static const sal_Unicode %s%d%d[] = {", pAsciiStr, count0, count1);
    writeStringCharacters(aChars);
    fprintf(m_f, "0x0};\n");
}

void OFileWriter::writeParameter(const sal_Char* pTagStr, const sal_Char* pAsciiStr, const ::rtl::OUString& aChars, const sal_Int16 count) const
{
    fprintf(m_f, "static const sal_Unicode %s%s%d[] = {", pTagStr, pAsciiStr, count);
    writeStringCharacters(aChars);
    fprintf(m_f, "0x0};\n");
}

void OFileWriter::writeParameter(const sal_Char* pTagStr, const sal_Char* pAsciiStr, const ::rtl::OUString& aChars) const
{
    fprintf(m_f, "static const sal_Unicode %s%s[] = {", pTagStr, pAsciiStr);
    writeStringCharacters(aChars);
    fprintf(m_f, "0x0};\n");
}

void OFileWriter::writeParameter(const sal_Char* pTagStr, const sal_Char* pAsciiStr, const ::rtl::OUString& aChars, sal_Int16 count0, sal_Int16 count1) const
{
    fprintf(m_f, "static const sal_Unicode %s%s%d%d[] = {", pTagStr, pAsciiStr, count0, count1);
    writeStringCharacters(aChars);
    fprintf(m_f, "0x0};\n");
}

void OFileWriter::flush(void) const
{
    fflush( m_f );
}

void OFileWriter::closeOutput(void) const
{
    if(m_f)
    {
        fclose( m_f );
        const_cast< OFileWriter * > ( this )->m_f = 0;
    }
}

<|endoftext|>


<commit_before>/* Copyright 2007-2015 QReal Research Group
 *
 * 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
 *
 * 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 "qrxcLauncher.h"

#include "plugins/metaEditor/metaEditorSupport/editorGenerator.h"
#include "qrgui/plugins/toolPluginInterface/usedInterfaces/mainWindowInterpretersInterface.h"
#include "qrrepo/repoApi.h"
#include "qrgui/mainWindow/errorReporter.h"
#include "qrxc/xmlCompiler.h"
#include "defs.h"

using namespace qReal;
using namespace qrRepo;
using namespace metaEditor;
using namespace gui;
using namespace editorPluginTestingFramework;

void QrxcLauncher::launchQrxc(const QString &fileName, const QString &pathToQRealSources, const QString &pathToGeneratedCode)
{
	qDebug() << "STARTING QRXC LAUNCHING";
	QString normalizedFileName = fileName;

	if (!fileName.contains(".qrs")) {
		normalizedFileName += ".qrs";
	}

	const RepoApi *mRepoApi = new RepoApi(normalizedFileName);
	ErrorReporter * const reporter = new ErrorReporter();
	EditorGenerator editorGenerator(*mRepoApi, *reporter);

	QDir dir(".");

	QHash<qReal::Id, QPair<QString, QString>> metamodelList = editorGenerator.getMetamodelList();

	dir.mkpath(pathToGeneratedCode + pathToQrxcGeneratedCode);
	for (const Id &key : metamodelList.keys()) {
		if (mRepoApi->isLogicalElement(key)) {
			const QString &directoryToGeneratedCode = generatePathToPlugin(pathToGeneratedCode);

			if (!dir.exists(directoryToGeneratedCode)) {
				dir.mkdir(directoryToGeneratedCode);
			}

			QPair<QString, QString> const metamodelNames = editorGenerator.generateEditor(key
					, pathToGeneratedCode + pathToQrxcGeneratedCode
					, pathToQRealSources);
		}
	}
	qDebug() << stringSeparator;
}

QString QrxcLauncher::generatePathToPlugin(const QString &pathToGeneratedCode)
{
	QString result;

	for (int i = 0; i < 3; i++) {
		result += "../";
	}

	result += pathToGeneratedCode + pathToQrxcGeneratedPlugin;

	return result;
}
<commit_msg>small corrections<commit_after>/* Copyright 2007-2015 QReal Research Group
 *
 * 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
 *
 * 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 "qrxcLauncher.h"

#include "plugins/metaEditor/metaEditorSupport/editorGenerator.h"
#include "qrgui/plugins/toolPluginInterface/usedInterfaces/mainWindowInterpretersInterface.h"
#include "qrrepo/repoApi.h"
#include "qrgui/mainWindow/errorReporter.h"
#include "qrxc/xmlCompiler.h"
#include "defs.h"

using namespace qReal;
using namespace qrRepo;
using namespace metaEditor;
using namespace gui;
using namespace editorPluginTestingFramework;

void QrxcLauncher::launchQrxc(const QString &fileName, const QString &pathToQRealSources, const QString &pathToGeneratedCode)
{
	qDebug() << "STARTING QRXC LAUNCHING";
	QString normalizedFileName = fileName;

	if (!fileName.contains(".qrs")) {
		normalizedFileName += ".qrs";
	}

	const RepoApi *mRepoApi = new RepoApi(normalizedFileName);
	ErrorReporter * const reporter = new ErrorReporter();
	EditorGenerator editorGenerator(*mRepoApi, *reporter);

	QDir dir(".");

	QHash<qReal::Id, QPair<QString, QString>> metamodelList = editorGenerator.getMetamodelList();

	dir.mkpath(pathToGeneratedCode + pathToQrxcGeneratedCode);
	for (const Id &key : metamodelList.keys()) {
		if (mRepoApi->isLogicalElement(key)) {
			const QString &directoryToGeneratedCode = generatePathToPlugin(pathToGeneratedCode);

			if (!dir.exists(directoryToGeneratedCode)) {
				dir.mkdir(directoryToGeneratedCode);
			}

			editorGenerator.generateEditor(key, pathToGeneratedCode + pathToQrxcGeneratedCode, pathToQRealSources);
		}
	}
	qDebug() << stringSeparator;
}

QString QrxcLauncher::generatePathToPlugin(const QString &pathToGeneratedCode)
{
	QString result;

	for (int i = 0; i < 3; i++) {
		result += "../";
	}

	result += pathToGeneratedCode + pathToQrxcGeneratedPlugin;

	return result;
}
<|endoftext|>


<commit_before>///
/// @file main.cpp
///
/// @Copyright (C) 2013 The Imaging Source GmbH; Edgar Thier <edgarthier@gmail.com>
///
/// main file for the commandline client that allows IP configuration of GigE cameras
///

#include "ConsoleManager.h"

#include <string>
#include <vector>
#include <iostream>

using namespace tis;

/// @name printHelp
/// @brief prints complete overview over possible actions
void printHelp ()
{
    std::cout << "\ntis_network - network module for GigE cameras"
              << "\n\nusage: tis_network [command]             - execute specified command"
              << "\n   or: tis_network [command] -c <camera> - execute command for given camera\n\n\n"

              << "Available commands:\n"
              << "    list     - list all available GigE cameras\n"
              << "    info     - print all information for camera\n"
              << "    set      - configure camera settings\n"
              << "    forceip  - force ip onto camera\n"
              << "    rescue   - broadcasts to MAC given settings\n"
              << "    upload   - upload new firmware to camera\n"
              << "    help     - print this text\n"
              << std::endl;

    std::cout << "\nAvailable parameter:\n"
              << "    -c <camera-serialnumber> - specify camera to use\n"
              << "    -h                       - same as help\n"
              << "    -i                       - same as info\n"
              << "    -l                       - same as list\n"
              << "    ip=X.X.X.X               - specifiy persistent ip that camera shall use\n"
              << "    subnet=X.X.X.X           - specifiy persistent subnetmask that camera shall use\n"
              << "    gateway=X.X.X.X          - specifiy persistent gateway that camera shall use\n"
              << "    dhcp=on/off              - toggle dhcp state\n"
              << "    static=on/off            - toggle static ip state\n"
              << "    name=\"xyz\"               - set name for camera; maximum 16 characters\n"
              << "    firmware=firmware.zip    - file containing new firmware\n"
              << std::endl;

    std::cout << "Examples:\n\n"

              << "    tis_network set gateway=192.168.0.1 -c 46210199\n"
              << "    tis_network forceip ip=192.168.0.100 subnet=255.255.255.0 gateway=192.168.0.1 -c 46210199\n\n"
              << std::endl;
}

void handleCommandlineArguments (const int argc, char* argv[])
{
    if (argc == 1)
    {
        printHelp();
        return;
    }

    // std::string makes things easier to handle
    // we don;t need the program name itself and just ignore it
    std::vector<std::string> args(argv+1, argv + argc);

    for (const auto& arg : args)
    {
        if ((arg.compare("help") == 0) || (arg.compare("-h") == 0))
        {
            printHelp();
            return;
        }
        else if ((arg.compare("list") == 0) || (arg.compare("-l") == 0))
        {
            listCameras();
            break;
        }
        else if ((arg.compare("info") == 0) || arg.compare("-i") == 0)
        {
            if (argc <= 2)
            {
                std::cout << "Not enough arguments." << std::endl;
                return;
            }
            printCameraInformation(args);
            break;
        }
        else if (arg.compare("set") == 0)
        {
            if (argc <= 2)
            {
                std::cout << "Not enough arguments." << std::endl;
                return;
            }
            setCamera(args);
            break;
        }
        else if (arg.compare("forceip") == 0)
        {
            forceIP(args);
            break;
        }
        else if (arg.compare("upload") == 0)
        {
            upgradeFirmware(args);
            break;
        }
        else if (arg.compare("rescue") == 0)
        {
            rescue(args);
            break;
        }
        else
        {
            // TODO allow it to write camera before other args so that -c does not break it
            std::cout << "Unknown parameter \"" << arg << "\"\n" << std::endl;
            return;
        }
    }
}

int main (int argc, char* argv[])
{
    handleCommandlineArguments(argc, argv);

    return 0;
}
<commit_msg>Wrapped handleCommandlineArguments loop in try/catch<commit_after>///
/// @file main.cpp
///
/// @Copyright (C) 2013 The Imaging Source GmbH; Edgar Thier <edgarthier@gmail.com>
///
/// main file for the commandline client that allows IP configuration of GigE cameras
///

#include "ConsoleManager.h"

#include <string>
#include <vector>
#include <iostream>
#include <exception>
#include <stdexcept>

using namespace tis;

/// @name printHelp
/// @brief prints complete overview over possible actions
void printHelp ()
{
    std::cout << "\ntis_network - network module for GigE cameras"
              << "\n\nusage: tis_network [command]             - execute specified command"
              << "\n   or: tis_network [command] -c <camera> - execute command for given camera\n\n\n"

              << "Available commands:\n"
              << "    list     - list all available GigE cameras\n"
              << "    info     - print all information for camera\n"
              << "    set      - configure camera settings\n"
              << "    forceip  - force ip onto camera\n"
              << "    rescue   - broadcasts to MAC given settings\n"
              << "    upload   - upload new firmware to camera\n"
              << "    help     - print this text\n"
              << std::endl;

    std::cout << "\nAvailable parameter:\n"
              << "    -c <camera-serialnumber> - specify camera to use\n"
              << "    -h                       - same as help\n"
              << "    -i                       - same as info\n"
              << "    -l                       - same as list\n"
              << "    ip=X.X.X.X               - specifiy persistent ip that camera shall use\n"
              << "    subnet=X.X.X.X           - specifiy persistent subnetmask that camera shall use\n"
              << "    gateway=X.X.X.X          - specifiy persistent gateway that camera shall use\n"
              << "    dhcp=on/off              - toggle dhcp state\n"
              << "    static=on/off            - toggle static ip state\n"
              << "    name=\"xyz\"               - set name for camera; maximum 16 characters\n"
              << "    firmware=firmware.zip    - file containing new firmware\n"
              << std::endl;

    std::cout << "Examples:\n\n"

              << "    tis_network set gateway=192.168.0.1 -c 46210199\n"
              << "    tis_network forceip ip=192.168.0.100 subnet=255.255.255.0 gateway=192.168.0.1 -c 46210199\n\n"
              << std::endl;
}

void handleCommandlineArguments (const int argc, char* argv[])
{
    if (argc == 1)
    {
        printHelp();
        return;
    }

    // std::string makes things easier to handle
    // we don;t need the program name itself and just ignore it
    std::vector<std::string> args(argv+1, argv + argc);

    try
    {
        for (const auto& arg : args)
        {
            if ((arg.compare("help") == 0) || (arg.compare("-h") == 0))
            {
                printHelp();
                return;
            }
            else if ((arg.compare("list") == 0) || (arg.compare("-l") == 0))
            {
                listCameras();
                break;
            }
            else if ((arg.compare("info") == 0) || arg.compare("-i") == 0)
            {
                if (argc <= 2)
                {
                    std::cout << "Not enough arguments." << std::endl;
                    return;
                }
                printCameraInformation(args);
                break;
            }
            else if (arg.compare("set") == 0)
            {
                if (argc <= 2)
                {
                    std::cout << "Not enough arguments." << std::endl;
                    return;
                }
                setCamera(args);
                break;
            }
            else if (arg.compare("forceip") == 0)
            {
                forceIP(args);
                break;
            }
            else if (arg.compare("upload") == 0)
            {
                upgradeFirmware(args);
                break;
            }
            else if (arg.compare("rescue") == 0)
            {
                rescue(args);
                break;
            }
            else
            {
                // TODO allow it to write camera before other args so that -c does not break it
                std::cout << "Unknown parameter \"" << arg << "\"\n" << std::endl;
                return;
            }
        }
    }
    catch (std::invalid_argument& exc)
    {
        std::cout << "\n" << exc.what()
                  << "\n" << std::endl;
        exit(1);
    }
}

int main (int argc, char* argv[])
{
    handleCommandlineArguments(argc, argv);

    return 0;
}
<|endoftext|>


<commit_before>//
//  JSONObject.hpp
//  G3MiOSSDK
//
//  Created by Oliver Koehler on 01/10/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#ifndef G3MiOSSDK_JSONObject_hpp
#define G3MiOSSDK_JSONObject_hpp

#include <map>
#include "JSONBaseObject.hpp"
#include "ILogger.hpp"

class JSONObject : public JSONBaseObject{
private:
  std::map<std::string, JSONBaseObject*> _entries;

public:
  ~JSONObject();
  JSONObject* getObject(){
    return this;
  }

  JSONBaseObject* getObjectForKey(std::string key);

  void putObject(const std::string key, JSONBaseObject* object);

  int getSize();

};

#endif
<commit_msg>still fixing java conversion issues<commit_after>//
//  JSONObject.hpp
//  G3MiOSSDK
//
//  Created by Oliver Koehler on 01/10/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#ifndef G3MiOSSDK_JSONObject_hpp
#define G3MiOSSDK_JSONObject_hpp

#include <map>
#include "JSONBaseObject.hpp"
#include "ILogger.hpp"

class JSONObject : public JSONBaseObject{
private:
  std::map<std::string, JSONBaseObject*> _entries;

public:
  ~JSONObject();
  JSONObject* getObject(){
    return this;
  }

  JSONBaseObject* getObjectForKey(const std::string key);

  void putObject(const std::string key, JSONBaseObject* object);

  int getSize();

};

#endif
<|endoftext|>


<commit_before>/*********************************************************************
 *
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2012, Worcester Polytechnic Institute
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the Worcester Polytechnic Institute nor the
 *     names of its contributors may be used to endorse or promote
 *     products derived from this software without specific prior
 *     written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 *   Author: Paul Malmsten
 *  Version: Sep 18, 2012
 *
 *********************************************************************/

/*!
 * \file extract_objects.cpp
 * \brief Given a .pcd file, this program extracts all objects and saves \
 *  them as separate object_*.pcd files in the working directory.
 *
 * \author Paul Malmsten, WPI - pmalmsten@wpi.edu
 * \date Sep 18, 2012
 */

#include <sstream>
#include <string>
#include <vector>

#include <pcl/io/pcd_io.h>

#include "rail_pcl_object_segmentation/pcl_segmenter.hpp"

/*!
 * \brief Main function for extract_objects executable.
 *
 * Reads the specified .pcd file, extracts all objects from it, and
 * saves them as separate .pcd files in the current working directory.
 *
 * Each created file is called object_I.pcd, where I is an integer
 * which increases from 0.
 */
int main(int argc, char** argv)
{
  if (argc < 2)
  {
    std::cerr << "Usage: extract_objects [options] path/to/input.pcd" << std::endl;
    std::cerr << " Options:" << std::endl;
    std::cerr << "   --debug            Saves all intermediate point clouds to disk, including" << std::endl;
    std::cerr << "                      the original minus planes and each extracted plane" << std::endl;
    std::cerr << " Extracted objects are saved to object_*.pcd in the" << std::endl << " current directory."
        << std::endl;
    return 1;
  }

  bool inDebugMode = (argc == 3 && strcmp(argv[1], "--debug") == 0);
  pcl::PCDWriter writer;

  // Read input file
  std::cout << "Reading '" << argv[argc - 1] << "'..." << std::endl;
  pcl::PCDReader reader;
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
  reader.read(argv[argc - 1], *cloud);

  // Down sample
  pcl::PointCloud<pcl::PointXYZ>::Ptr processed_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(
      new pcl::PointCloud<pcl::PointXYZ>());

  rail::DownsampleCloud<pcl::PointXYZ>(cloud, processed_cloud);

  if(inDebugMode) {
      std::cout << "Writing downsampled cloud as 'input_downsampled_rgb.pcd'" << std::endl;
      writer.write("input_downsampled_rgb.pcd", *processed_cloud);
  }

  // Remove planes
  std::vector<rail::DiscoveredPlanePtr> planes;
  rail::ExtractPlanes<pcl::PointXYZ>(processed_cloud, processed_cloud, planes);

  if(inDebugMode) {
      // Dump original w/o planes
      std::cout << "Writing input without large planes as 'input_minus_planes_rgb.pcd'" << std::endl;
      writer.write("input_minus_planes_rgb.pcd", *processed_cloud);

      // Dump planes
      unsigned int i = 0;
      for(std::vector<rail::DiscoveredPlanePtr>::iterator it = planes.begin(); it != planes.end(); ++it) {
          std::stringstream fileName;
          fileName << "extracted_plane_" << i++ << "_rgb.pcd";

          std::cout << " Writing extracted plane to " << fileName.str() << std::endl;
          writer.write(fileName.str(), (*(*it)).planeCloud);
      }
  }

  // Extract objects
  std::cout << "Extracting objects..." << std::endl;

  std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> objects;
  rail::ExtractObjectClouds<pcl::PointXYZ>(processed_cloud, objects);

  std::cout << " Extracted " << objects.size() << " objects." << std::endl;

  // Save results
  int i = 0;
  for (std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>::iterator it = objects.begin(); it != objects.end(); ++it)
  {
    std::stringstream fileName;
    fileName << "object_" << i << "_rgb.pcd";

    std::cout << "Writing " << fileName.str() << std::endl;

    writer.write(fileName.str(), *(*it));
    i++;
  }

  return 0;
}
<commit_msg>Fixed file naming bugs in extract_objects<commit_after>/*********************************************************************
 *
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2012, Worcester Polytechnic Institute
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the Worcester Polytechnic Institute nor the
 *     names of its contributors may be used to endorse or promote
 *     products derived from this software without specific prior
 *     written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 *   Author: Paul Malmsten
 *  Version: Sep 18, 2012
 *
 *********************************************************************/

/*!
 * \file extract_objects.cpp
 * \brief Given a .pcd file, this program extracts all objects and saves \
 *  them as separate object_*.pcd files in the working directory.
 *
 * \author Paul Malmsten, WPI - pmalmsten@wpi.edu
 * \date Sep 18, 2012
 */

#include <sstream>
#include <string>
#include <vector>

#include <pcl/io/pcd_io.h>

#include "rail_pcl_object_segmentation/pcl_segmenter.hpp"

/*!
 * \brief Main function for extract_objects executable.
 *
 * Reads the specified .pcd file, extracts all objects from it, and
 * saves them as separate .pcd files in the current working directory.
 *
 * Each created file is called object_I.pcd, where I is an integer
 * which increases from 0.
 */
int main(int argc, char** argv)
{
  if (argc < 2)
  {
    std::cerr << "Usage: extract_objects [options] path/to/input.pcd" << std::endl;
    std::cerr << " Options:" << std::endl;
    std::cerr << "   --debug            Saves all intermediate point clouds to disk, including" << std::endl;
    std::cerr << "                      the original minus planes and each extracted plane" << std::endl;
    std::cerr << " Extracted objects are saved to object_*.pcd in the" << std::endl << " current directory."
        << std::endl;
    return 1;
  }

  bool inDebugMode = (argc == 3 && strcmp(argv[1], "--debug") == 0);
  pcl::PCDWriter writer;

  // Read input file
  std::cout << "Reading '" << argv[argc - 1] << "'..." << std::endl;
  pcl::PCDReader reader;
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
  reader.read(argv[argc - 1], *cloud);

  // Down sample
  pcl::PointCloud<pcl::PointXYZ>::Ptr processed_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(
      new pcl::PointCloud<pcl::PointXYZ>());

  rail::DownsampleCloud<pcl::PointXYZ>(cloud, processed_cloud);

  if(inDebugMode) {
      std::cout << "Writing downsampled cloud as 'input_downsampled.pcd'" << std::endl;
      writer.write("input_downsampled.pcd", *processed_cloud);
  }

  // Remove planes
  std::vector<rail::DiscoveredPlanePtr> planes;
  rail::ExtractPlanes<pcl::PointXYZ>(processed_cloud, processed_cloud, planes);

  if(inDebugMode) {
      // Dump original w/o planes
      std::cout << "Writing input without large planes as 'input_minus_planes.pcd'" << std::endl;
      writer.write("input_minus_planes.pcd", *processed_cloud);

      // Dump planes
      unsigned int i = 0;
      for(std::vector<rail::DiscoveredPlanePtr>::iterator it = planes.begin(); it != planes.end(); ++it) {
          std::stringstream fileName;
          fileName << "extracted_plane" << i++ << ".pcd";

          std::cout << " Writing extracted plane to " << fileName.str() << std::endl;
          writer.write(fileName.str(), (*(*it)).planeCloud);
      }
  }

  // Extract objects
  std::cout << "Extracting objects..." << std::endl;

  std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> objects;
  rail::ExtractObjectClouds<pcl::PointXYZ>(processed_cloud, objects);

  std::cout << " Extracted " << objects.size() << " objects." << std::endl;

  // Save results
  int i = 0;
  for (std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>::iterator it = objects.begin(); it != objects.end(); ++it)
  {
    std::stringstream fileName;
    fileName << "object_" << i << ".pcd";

    std::cout << "Writing " << fileName.str() << std::endl;

    writer.write(fileName.str(), *(*it));
    i++;
  }

  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/host/capturer.h"

namespace remoting {

Capturer::Capturer()
    : width_(0),
      height_(0),
      pixel_format_(PixelFormatInvalid),
      bytes_per_pixel_(0),
      bytes_per_row_(0),
      current_buffer_(0) {
}

Capturer::~Capturer() {
}

void Capturer::GetDirtyRects(DirtyRects* rects) const {
  *rects = dirty_rects_;
}

int Capturer::GetWidth() const {
  return width_;
}

int Capturer::GetHeight() const {
  return height_;
}

PixelFormat Capturer::GetPixelFormat() const {
  return pixel_format_;
}

void Capturer::InvalidateRect(gfx::Rect dirty_rect) {
  inval_rects_.push_back(dirty_rect);
}

void Capturer::FinishCapture(Task* done_task) {
  done_task->Run();
  delete done_task;

  // Select the next buffer to be the current buffer.
  current_buffer_ = ++current_buffer_ % kNumBuffers;
}

}  // namespace remoting
<commit_msg>Coverity: Fix undefined assignment evaluation order in remoting::Capturer::FinishCapture.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/host/capturer.h"

namespace remoting {

Capturer::Capturer()
    : width_(0),
      height_(0),
      pixel_format_(PixelFormatInvalid),
      bytes_per_pixel_(0),
      bytes_per_row_(0),
      current_buffer_(0) {
}

Capturer::~Capturer() {
}

void Capturer::GetDirtyRects(DirtyRects* rects) const {
  *rects = dirty_rects_;
}

int Capturer::GetWidth() const {
  return width_;
}

int Capturer::GetHeight() const {
  return height_;
}

PixelFormat Capturer::GetPixelFormat() const {
  return pixel_format_;
}

void Capturer::InvalidateRect(gfx::Rect dirty_rect) {
  inval_rects_.push_back(dirty_rect);
}

void Capturer::FinishCapture(Task* done_task) {
  done_task->Run();
  delete done_task;

  // Select the next buffer to be the current buffer.
  current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
}

}  // namespace remoting
<|endoftext|>


<commit_before>// IVSHMEM-test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#define TEST_START(name) printf("Test: %s...", name)
#define TEST_PASS() printf("PASS\n")
#define TEST_FAIL(reason) printf("FAIL - %s\n", reason)

int main()
{
	HDEVINFO deviceInfoSet;
	DWORD    deviceIndex;

	PSP_DEVICE_INTERFACE_DETAIL_DATA infData = NULL;
	HANDLE   devHandle = INVALID_HANDLE_VALUE;

	deviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE);
	SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
	ZeroMemory(&deviceInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA));
	deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

	deviceIndex = 0;
	while (1)
	{
		TEST_START("Find device");
		if (SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &GUID_DEVINTERFACE_IVSHMEM, 0, &deviceInterfaceData) == FALSE)
		{
			DWORD error = GetLastError();
			if (error == ERROR_NO_MORE_ITEMS)
			{
				TEST_FAIL("Unable to enumerate the device, is it attached?");
				break;
			}

			TEST_FAIL("SetupDiEnumDeviceInterfaces failed");
			break;
		}
		TEST_PASS();

		TEST_START("Get device name length");
		DWORD reqSize = 0;
		// this returns false even though we succeed in getting the size
		SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, NULL, 0, &reqSize, NULL);
		if (!reqSize)
		{
			TEST_FAIL("SetupDiGetDeviceInterfaceDetail");
			break;
		}
		TEST_PASS();

		TEST_START("Get device name");
		infData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(reqSize);
		infData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
		if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, infData, reqSize, NULL, NULL))
		{
			TEST_FAIL("SetupDiGetDeviceInterfaceDetail");
			break;
		}
		TEST_PASS();

		TEST_START("Open device");
		devHandle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0);
		if (devHandle == INVALID_HANDLE_VALUE)
		{
			TEST_FAIL("CreateFile returned INVALID_HANDLE_VALUE");
			break;
		}
		TEST_PASS();

		TEST_START("IOCTL_IVSHMEM_REQUEST_PEERID");
		IVSHMEM_PEERID peer = 0;
		ULONG   ulReturnedLength = 0;

		if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_PEERID, NULL, 0, &peer, sizeof(IVSHMEM_PEERID), &ulReturnedLength, NULL))
		{
			TEST_FAIL("DeviceIoControl");
			printf("Error 0x%x\n", GetLastError());
			break;
		}
		TEST_PASS();

		printf("Peer: %u\n", peer);

		TEST_START("IOCTL_IVSHMEM_REQUEST_SIZE");
		IVSHMEM_SIZE size = 0;
		if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &size, sizeof(IVSHMEM_SIZE), &ulReturnedLength, NULL))
		{
			TEST_FAIL("DeviceIoControl");
			break;
		}

		if (size == 0)
		{
			TEST_FAIL("Size should not be zero");
			break;
		}
		TEST_PASS();

		printf("Size: %I64u\n", size);

		TEST_START("IOCTL_IVSHMEM_REQUEST_MMAP");
		IVSHMEM_MMAP_CONFIG conf;
		IVSHMEM_MMAP map;

		conf.cacheMode = IVSHMEM_CACHE_NONCACHED;
		ZeroMemory(&map, sizeof(IVSHMEM_MMAP));
		if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_MMAP, &conf, sizeof(IVSHMEM_MMAP_CONFIG), &map, sizeof(IVSHMEM_MMAP), &ulReturnedLength, NULL))
		{
			TEST_FAIL("DeviceIoControl");
			break;
		}

		if (!map.ptr)
		{
			TEST_FAIL("NULL pointer to mapping returned");
			break;
		}

		if (map.size != size)
		{
			TEST_FAIL("Incorrect size");
			break;
		}
		TEST_PASS();

		TEST_START("Mapping more then once fails");
		if (DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_MMAP, &conf, sizeof(IVSHMEM_MMAP_CONFIG), &map, sizeof(IVSHMEM_MMAP), &ulReturnedLength, NULL))
		{
			TEST_FAIL("mapping succeeded, this should not happen!");
			break;
		}
		TEST_PASS();

		TEST_START("Mapping from another handle fails");
		HANDLE devHandle2 = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0);
		if (!devHandle2)
		{
			TEST_FAIL("Failed to open second handle");
			break;
		}
		if (DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_MMAP, &conf, sizeof(IVSHMEM_MMAP_CONFIG), &map, sizeof(IVSHMEM_MMAP), &ulReturnedLength, NULL))
		{
			TEST_FAIL("mapping succeeded, this should not happen!");
			break;
		}
		CloseHandle(devHandle2);
		TEST_PASS();

		TEST_START("IOCTL_IVSHMEM_RING_DOORBELL");
		IVSHMEM_RING ring;
		ring.peerID = 0;
		ring.vector = 0;
		if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_RING_DOORBELL, &ring, sizeof(IVSHMEM_RING), NULL, 0, &ulReturnedLength, NULL))
		{
			TEST_FAIL("DeviceIoControl");
			break;
		}
		TEST_PASS();

		TEST_START("IOCTL_IVSHMEM_RELEASE_MMAP");
		if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_RELEASE_MMAP, NULL, 0, NULL, 0, &ulReturnedLength, NULL))
		{
			TEST_FAIL("DeviceIoControl");
			break;
		}
		TEST_PASS();

		TEST_START("Closing handle releases mapping");
		CloseHandle(devHandle);
		devHandle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0);
		if (devHandle == INVALID_HANDLE_VALUE)
		{
			TEST_FAIL("Failed to re-open handle");
			break;
		}
		if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_MMAP, &conf, sizeof(IVSHMEM_MMAP_CONFIG), &map, sizeof(IVSHMEM_MMAP), &ulReturnedLength, NULL))
		{
			TEST_FAIL("Mapping failed!");
			break;
		}
		TEST_PASS();

		TEST_START("Shared memory actually works");
		memset(map.ptr, 0xAA, (size_t)map.size);
		CloseHandle(devHandle);
		devHandle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0);
		if (devHandle == INVALID_HANDLE_VALUE)
		{
			TEST_FAIL("Failed to re-open handle");
			break;
		}
		if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_MMAP, &conf, sizeof(IVSHMEM_MMAP_CONFIG), &map, sizeof(IVSHMEM_MMAP), &ulReturnedLength, NULL))
		{
			TEST_FAIL("Mapping failed!");
			break;
		}

		bool fail = false;
		unsigned char *data = (unsigned char *)map.ptr;
		for (UINT64 i = 0; i < map.size; ++i)
			if (data[i] != 0xAA)
			{
				TEST_FAIL("Invalid data read back");
				fail = true;
				break;
			}
		if (fail)
			break;
		TEST_PASS();

		if (map.vectors > 0)
		{
			TEST_START("Check events work, send interrupt 0 to this peer");
			IVSHMEM_EVENT event;
			event.event = CreateEvent(NULL, TRUE, FALSE, L"TEST_EVENT");
			event.vector = 0;
			event.singleShot = TRUE;
			if (event.event == INVALID_HANDLE_VALUE)
			{
				TEST_FAIL("Failed to create the event");
				break;
			}
			if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_REGISTER_EVENT, &event, sizeof(IVSHMEM_EVENT), NULL, 0, &ulReturnedLength, NULL))
			{
				TEST_FAIL("Register event failed!");
				CloseHandle(event.event);
				break;
			}

			if (WaitForSingleObject(event.event, INFINITE) != WAIT_OBJECT_0)
			{
				TEST_FAIL("WaitForSingleObject failed!");
				CloseHandle(event.event);
				break;
			}
			CloseHandle(event.event);
			TEST_PASS();
		}

		break;
	}

	if (devHandle != INVALID_HANDLE_VALUE)
		CloseHandle(devHandle);

	if (infData)
		free(infData);

	SetupDiDestroyDeviceInfoList(deviceInfoSet);

    return 0;
}
<commit_msg>[ivshmem] ut: cosmetics<commit_after>// IVSHMEM-test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#define TEST_START(name) printf("Test: %s...", name)
#define TEST_PASS() printf("PASS\n")
#define TEST_FAIL(reason) printf("FAIL - %s\n", reason)

int main()
{
    HDEVINFO deviceInfoSet;
    DWORD    deviceIndex;

    PSP_DEVICE_INTERFACE_DETAIL_DATA infData = NULL;
    HANDLE   devHandle = INVALID_HANDLE_VALUE;

    deviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE);
    SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
    ZeroMemory(&deviceInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA));
    deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

    deviceIndex = 0;
    while (1)
    {
        TEST_START("Find device");
        if (SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &GUID_DEVINTERFACE_IVSHMEM, 0, &deviceInterfaceData) == FALSE)
        {
            DWORD error = GetLastError();
            if (error == ERROR_NO_MORE_ITEMS)
            {
                TEST_FAIL("Unable to enumerate the device, is it attached?");
                break;
            }

            TEST_FAIL("SetupDiEnumDeviceInterfaces failed");
            break;
        }
        TEST_PASS();

        TEST_START("Get device name length");
        DWORD reqSize = 0;
        // this returns false even though we succeed in getting the size
        SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, NULL, 0, &reqSize, NULL);
        if (!reqSize)
        {
            TEST_FAIL("SetupDiGetDeviceInterfaceDetail");
            break;
        }
        TEST_PASS();

        TEST_START("Get device name");
        infData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(reqSize);
        infData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, infData, reqSize, NULL, NULL))
        {
            TEST_FAIL("SetupDiGetDeviceInterfaceDetail");
            break;
        }
        TEST_PASS();

        TEST_START("Open device");
        devHandle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0);
        if (devHandle == INVALID_HANDLE_VALUE)
        {
            TEST_FAIL("CreateFile returned INVALID_HANDLE_VALUE");
            break;
        }
        TEST_PASS();

        TEST_START("IOCTL_IVSHMEM_REQUEST_PEERID");
        IVSHMEM_PEERID peer = 0;
        ULONG   ulReturnedLength = 0;

        if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_PEERID, NULL, 0, &peer, sizeof(IVSHMEM_PEERID), &ulReturnedLength, NULL))
        {
            TEST_FAIL("DeviceIoControl");
            printf("Error 0x%x\n", GetLastError());
            break;
        }
        TEST_PASS();

        printf("Peer: %u\n", peer);

        TEST_START("IOCTL_IVSHMEM_REQUEST_SIZE");
        IVSHMEM_SIZE size = 0;
        if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &size, sizeof(IVSHMEM_SIZE), &ulReturnedLength, NULL))
        {
            TEST_FAIL("DeviceIoControl");
            break;
        }

        if (size == 0)
        {
            TEST_FAIL("Size should not be zero");
            break;
        }
        TEST_PASS();

        printf("Size: %I64u\n", size);

        TEST_START("IOCTL_IVSHMEM_REQUEST_MMAP");
        IVSHMEM_MMAP_CONFIG conf;
        IVSHMEM_MMAP map;

        conf.cacheMode = IVSHMEM_CACHE_NONCACHED;
        ZeroMemory(&map, sizeof(IVSHMEM_MMAP));
        if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_MMAP, &conf, sizeof(IVSHMEM_MMAP_CONFIG), &map, sizeof(IVSHMEM_MMAP), &ulReturnedLength, NULL))
        {
            TEST_FAIL("DeviceIoControl");
            break;
        }

        if (!map.ptr)
        {
            TEST_FAIL("NULL pointer to mapping returned");
            break;
        }

        if (map.size != size)
        {
            TEST_FAIL("Incorrect size");
            break;
        }
        TEST_PASS();

        TEST_START("Mapping more then once fails");
        if (DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_MMAP, &conf, sizeof(IVSHMEM_MMAP_CONFIG), &map, sizeof(IVSHMEM_MMAP), &ulReturnedLength, NULL))
        {
            TEST_FAIL("mapping succeeded, this should not happen!");
            break;
        }
        TEST_PASS();

        TEST_START("Mapping from another handle fails");
        HANDLE devHandle2 = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0);
        if (!devHandle2)
        {
            TEST_FAIL("Failed to open second handle");
            break;
        }
        if (DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_MMAP, &conf, sizeof(IVSHMEM_MMAP_CONFIG), &map, sizeof(IVSHMEM_MMAP), &ulReturnedLength, NULL))
        {
            TEST_FAIL("mapping succeeded, this should not happen!");
            break;
        }
        CloseHandle(devHandle2);
        TEST_PASS();

        TEST_START("IOCTL_IVSHMEM_RING_DOORBELL");
        IVSHMEM_RING ring;
        ring.peerID = 0;
        ring.vector = 0;
        if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_RING_DOORBELL, &ring, sizeof(IVSHMEM_RING), NULL, 0, &ulReturnedLength, NULL))
        {
            TEST_FAIL("DeviceIoControl");
            break;
        }
        TEST_PASS();

        TEST_START("IOCTL_IVSHMEM_RELEASE_MMAP");
        if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_RELEASE_MMAP, NULL, 0, NULL, 0, &ulReturnedLength, NULL))
        {
            TEST_FAIL("DeviceIoControl");
            break;
        }
        TEST_PASS();

        TEST_START("Closing handle releases mapping");
        CloseHandle(devHandle);
        devHandle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0);
        if (devHandle == INVALID_HANDLE_VALUE)
        {
            TEST_FAIL("Failed to re-open handle");
            break;
        }
        if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_MMAP, &conf, sizeof(IVSHMEM_MMAP_CONFIG), &map, sizeof(IVSHMEM_MMAP), &ulReturnedLength, NULL))
        {
            TEST_FAIL("Mapping failed!");
            break;
        }
        TEST_PASS();

        TEST_START("Shared memory actually works");
        memset(map.ptr, 0xAA, (size_t)map.size);
        CloseHandle(devHandle);
        devHandle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0);
        if (devHandle == INVALID_HANDLE_VALUE)
        {
            TEST_FAIL("Failed to re-open handle");
            break;
        }
        if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_MMAP, &conf, sizeof(IVSHMEM_MMAP_CONFIG), &map, sizeof(IVSHMEM_MMAP), &ulReturnedLength, NULL))
        {
            TEST_FAIL("Mapping failed!");
            break;
        }

        bool fail = false;
        unsigned char *data = (unsigned char *)map.ptr;
        for (UINT64 i = 0; i < map.size; ++i)
            if (data[i] != 0xAA)
            {
                TEST_FAIL("Invalid data read back");
                fail = true;
                break;
            }
        if (fail)
            break;
        TEST_PASS();

        if (map.vectors > 0)
        {
            TEST_START("Check events work, send interrupt 0 to this peer");
            IVSHMEM_EVENT event;
            event.event = CreateEvent(NULL, TRUE, FALSE, L"TEST_EVENT");
            event.vector = 0;
            event.singleShot = TRUE;
            if (event.event == INVALID_HANDLE_VALUE)
            {
                TEST_FAIL("Failed to create the event");
                break;
            }
            if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_REGISTER_EVENT, &event, sizeof(IVSHMEM_EVENT), NULL, 0, &ulReturnedLength, NULL))
            {
                TEST_FAIL("Register event failed!");
                CloseHandle(event.event);
                break;
            }

            if (WaitForSingleObject(event.event, INFINITE) != WAIT_OBJECT_0)
            {
                TEST_FAIL("WaitForSingleObject failed!");
                CloseHandle(event.event);
                break;
            }
            CloseHandle(event.event);
            TEST_PASS();
        }

        break;
    }

    if (devHandle != INVALID_HANDLE_VALUE)
        CloseHandle(devHandle);

    if (infData)
        free(infData);

    SetupDiDestroyDeviceInfoList(deviceInfoSet);

    return 0;
}
<|endoftext|>