Point Cloud Library (PCL)  1.5.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
file_io.h
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2009, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * $Id: file_io.h 4702 2012-02-23 09:39:33Z gedikli $
00035  *
00036  */
00037 
00038 #ifndef PCL_IO_FILE_IO_H_
00039 #define PCL_IO_FILE_IO_H_
00040 
00041 #include <pcl/pcl_macros.h>
00042 #include <pcl/common/io.h>
00043 #include <boost/numeric/conversion/cast.hpp>
00044 #include <cmath>
00045 #include <sstream>
00046 
00047 namespace pcl
00048 {
00054   class PCL_EXPORTS FileReader
00055   {
00056     public:
00058       FileReader() {}
00060       virtual ~FileReader() {}
00078       virtual int 
00079       readHeader (const std::string &file_name, sensor_msgs::PointCloud2 &cloud, 
00080                   Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, 
00081                   int &file_version, int &data_type, int &data_idx) = 0;
00082 
00090       virtual int 
00091       read (const std::string &file_name, sensor_msgs::PointCloud2 &cloud, 
00092             Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, int &file_version) = 0;
00093 
00104       int 
00105       read (const std::string &file_name, sensor_msgs::PointCloud2 &cloud)
00106       {
00107         Eigen::Vector4f origin;
00108         Eigen::Quaternionf orientation;
00109         int file_version;
00110         return read(file_name, cloud, origin, orientation, file_version);
00111       }
00112 
00117       template<typename PointT> inline int
00118       read (const std::string &file_name, pcl::PointCloud<PointT> &cloud)
00119       {
00120         sensor_msgs::PointCloud2 blob;
00121         int file_version;
00122         int res = read (file_name, blob, cloud.sensor_origin_, cloud.sensor_orientation_, 
00123                         file_version);
00124 
00125         // Exit in case of error
00126         if (res < 0)
00127           return res;
00128         pcl::fromROSMsg (blob, cloud);
00129         return 0;
00130       }
00131   };
00132 
00138   class PCL_EXPORTS FileWriter
00139   {
00140     public:
00142       FileWriter () {}
00143 
00145       virtual ~FileWriter () {}
00146 
00155       virtual int
00156       write (const std::string &file_name, const sensor_msgs::PointCloud2 &cloud, 
00157              const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (), 
00158              const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
00159              const bool binary = false) = 0;
00160 
00169       inline int
00170       write (const std::string &file_name, const sensor_msgs::PointCloud2::ConstPtr &cloud, 
00171              const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (), 
00172              const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
00173              const bool binary = false)
00174       {
00175         return (write (file_name, *cloud, origin, orientation, binary));
00176       }
00177 
00184       template<typename PointT> inline int
00185       write (const std::string &file_name, 
00186              const pcl::PointCloud<PointT> &cloud, 
00187              const bool binary = false)
00188       {
00189         Eigen::Vector4f origin = cloud.sensor_origin_;
00190         Eigen::Quaternionf orientation = cloud.sensor_orientation_;
00191 
00192         sensor_msgs::PointCloud2 blob;
00193         pcl::toROSMsg (cloud, blob);
00194 
00195         // Save the data
00196         return (write (file_name, blob, origin, orientation, binary));
00197       }
00198   };
00199 
00211   template <typename Type> inline void
00212   copyValueString (const sensor_msgs::PointCloud2 &cloud, 
00213                    const unsigned int point_index, 
00214                    const int point_size, 
00215                    const unsigned int field_idx, 
00216                    const unsigned int fields_count, 
00217                    std::ostream &stream)
00218   {
00219     Type value;
00220     memcpy (&value, &cloud.data[point_index * point_size + cloud.fields[field_idx].offset + fields_count * sizeof (Type)], sizeof (Type));
00221     if (pcl_isnan (value))
00222       stream << "nan";
00223     else
00224       stream << boost::numeric_cast<Type>(value);
00225   }
00226   template <> inline void
00227   copyValueString<int8_t> (const sensor_msgs::PointCloud2 &cloud, 
00228                            const unsigned int point_index, 
00229                            const int point_size, 
00230                            const unsigned int field_idx, 
00231                            const unsigned int fields_count, 
00232                            std::ostream &stream)
00233   {
00234     int8_t value;
00235     memcpy (&value, &cloud.data[point_index * point_size + cloud.fields[field_idx].offset + fields_count * sizeof (int8_t)], sizeof (int8_t));
00236     if (pcl_isnan (value))
00237       stream << "nan";
00238     else
00239       // Numeric cast doesn't give us what we want for int8_t
00240       stream << boost::numeric_cast<int>(value);
00241   }
00242   template <> inline void
00243   copyValueString<uint8_t> (const sensor_msgs::PointCloud2 &cloud, 
00244                             const unsigned int point_index, 
00245                             const int point_size, 
00246                             const unsigned int field_idx, 
00247                             const unsigned int fields_count, 
00248                             std::ostream &stream)
00249   {
00250     uint8_t value;
00251     memcpy (&value, &cloud.data[point_index * point_size + cloud.fields[field_idx].offset + fields_count * sizeof (uint8_t)], sizeof (uint8_t));
00252     if (pcl_isnan (value))
00253       stream << "nan";
00254     else
00255       // Numeric cast doesn't give us what we want for uint8_t
00256       stream << boost::numeric_cast<int>(value);
00257   }
00258 
00269   template <typename Type> inline bool
00270   isValueFinite (const sensor_msgs::PointCloud2 &cloud, 
00271                  const unsigned int point_index, 
00272                  const int point_size, 
00273                  const unsigned int field_idx, 
00274                  const unsigned int fields_count)
00275   {
00276     Type value;
00277     memcpy (&value, &cloud.data[point_index * point_size + cloud.fields[field_idx].offset + fields_count * sizeof (Type)], sizeof (Type));
00278     if (!pcl_isfinite (value))
00279       return (false);
00280     return (true);
00281   }
00282 
00294   template <typename Type> inline void
00295   copyStringValue (const std::string &st, sensor_msgs::PointCloud2 &cloud,
00296                    unsigned int point_index, unsigned int field_idx, unsigned int fields_count)
00297   {
00298     Type value;
00299     if (st == "nan")
00300     {
00301       value = std::numeric_limits<Type>::quiet_NaN ();
00302       cloud.is_dense = false;
00303     }
00304     else
00305     {
00306       std::istringstream is (st);
00307       is.imbue (std::locale::classic ());
00308       is >> value;
00309     }
00310 
00311     memcpy (&cloud.data[point_index * cloud.point_step + 
00312                         cloud.fields[field_idx].offset + 
00313                         fields_count * sizeof (Type)], (char*)&value, sizeof (Type));
00314   }
00315 
00316   template <> inline void
00317   copyStringValue<int8_t> (const std::string &st, sensor_msgs::PointCloud2 &cloud,
00318                            unsigned int point_index, unsigned int field_idx, unsigned int fields_count)
00319   {
00320     int8_t value;
00321     if (st == "nan")
00322     {
00323       value = std::numeric_limits<int>::quiet_NaN ();
00324       cloud.is_dense = false;
00325     }
00326     else
00327     {
00328       int val;
00329       std::istringstream is (st);
00330       is.imbue (std::locale::classic ());
00331       is >> val;
00332       value = val;
00333     }
00334 
00335     memcpy (&cloud.data[point_index * cloud.point_step + 
00336                         cloud.fields[field_idx].offset + 
00337                         fields_count * sizeof (int8_t)], (char*)&value, sizeof (int8_t));
00338   }
00339 
00340   template <> inline void
00341   copyStringValue<uint8_t> (const std::string &st, sensor_msgs::PointCloud2 &cloud,
00342                            unsigned int point_index, unsigned int field_idx, unsigned int fields_count)
00343   {
00344     uint8_t value;
00345     if (st == "nan")
00346     {
00347       value = std::numeric_limits<int>::quiet_NaN ();
00348       cloud.is_dense = false;
00349     }
00350     else
00351     {
00352       int val;
00353       std::istringstream is (st);
00354       is.imbue (std::locale::classic ());
00355       is >> val;
00356       value = val;
00357     }
00358 
00359     memcpy (&cloud.data[point_index * cloud.point_step + 
00360                         cloud.fields[field_idx].offset + 
00361                         fields_count * sizeof (uint8_t)], (char*)&value, sizeof (uint8_t));
00362   }
00363 }
00364 
00365 #endif  //#ifndef PCL_IO_FILE_IO_H_