ait-survey

pcd_io.cpp

Aug 24th, 2015
366
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 61.85 KB | None | 0 0
  1. /*
  2.  * Software License Agreement (BSD License)
  3.  *
  4.  *  Point Cloud Library (PCL) - www.pointclouds.org
  5.  *  Copyright (c) 2010-2011, Willow Garage, Inc.
  6.  *
  7.  *  All rights reserved.
  8.  *
  9.  *  Redistribution and use in source and binary forms, with or without
  10.  *  modification, are permitted provided that the following conditions
  11.  *  are met:
  12.  *
  13.  *   * Redistributions of source code must retain the above copyright
  14.  *     notice, this list of conditions and the following disclaimer.
  15.  *   * Redistributions in binary form must reproduce the above
  16.  *     copyright notice, this list of conditions and the following
  17.  *     disclaimer in the documentation and/or other materials provided
  18.  *     with the distribution.
  19.  *   * Neither the name of Willow Garage, Inc. nor the names of its
  20.  *     contributors may be used to endorse or promote products derived
  21.  *     from this software without specific prior written permission.
  22.  *
  23.  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  24.  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  25.  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  26.  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  27.  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  28.  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  29.  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30.  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  31.  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  33.  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  34.  *  POSSIBILITY OF SUCH DAMAGE.
  35.  *
  36.  * $Id$
  37.  *
  38.  */
  39.  
  40. #include <fstream>
  41. #include <fcntl.h>
  42. #include <string>
  43. #include <stdlib.h>
  44. #include <pcl/io/boost.h>
  45. #include <pcl/common/io.h>
  46. #include <pcl/io/pcd_io.h>
  47. #include <pcl/io/lzf.h>
  48. #include <pcl/console/time.h>
  49. #include <iostream>
  50. #include <cstring>
  51. #include <cerrno>
  52.  
  53. #ifdef _WIN32
  54. # include <io.h>
  55. # include <windows.h>
  56. # define pcl_open                    _open
  57. # define pcl_close(fd)               _close(fd)
  58. # define pcl_lseek(fd,offset,origin) _lseek(fd,offset,origin)
  59. #else
  60. # include <sys/mman.h>
  61. # define pcl_open                    open
  62. # define pcl_close(fd)               close(fd)
  63. # define pcl_lseek(fd,offset,origin) lseek(fd,offset,origin)
  64. #endif
  65. #include <boost/version.hpp>
  66.  
  67. ///////////////////////////////////////////////////////////////////////////////////////////
  68. void
  69. pcl::PCDWriter::setLockingPermissions (const std::string &file_name,
  70.                                        boost::interprocess::file_lock &lock)
  71. {
  72.   (void)file_name;
  73.   (void)lock;
  74. #ifndef WIN32
  75.   // Boost version 1.49 introduced permissions
  76. #if BOOST_VERSION >= 104900
  77.   // Attempt to lock the file.
  78.   // For mandatory locking, the filesystem must be mounted with the "mand" option in Linux (see http://www.hackinglinuxexposed.com/articles/20030623.html)
  79.   lock = boost::interprocess::file_lock (file_name.c_str ());
  80.   if (lock.try_lock ())
  81.     PCL_DEBUG ("[pcl::PCDWriter::setLockingPermissions] File %s locked successfully.\n", file_name.c_str ());
  82.   else
  83.     PCL_DEBUG ("[pcl::PCDWriter::setLockingPermissions] File %s could not be locked!\n", file_name.c_str ());
  84.  
  85.   namespace fs = boost::filesystem;
  86.   fs::permissions (fs::path (file_name), fs::add_perms | fs::set_gid_on_exe);
  87. #endif
  88. #endif
  89. }
  90.  
  91. ///////////////////////////////////////////////////////////////////////////////////////////
  92. void
  93. pcl::PCDWriter::resetLockingPermissions (const std::string &file_name,
  94.                                          boost::interprocess::file_lock &lock)
  95. {
  96.   (void)file_name;
  97.   (void)lock;
  98. #ifndef WIN32
  99.   // Boost version 1.49 introduced permissions
  100. #if BOOST_VERSION >= 104900
  101.   (void)file_name;
  102.   namespace fs = boost::filesystem;
  103.   fs::permissions (fs::path (file_name), fs::remove_perms | fs::set_gid_on_exe);
  104.   lock.unlock ();
  105. #endif
  106. #endif
  107. }
  108.  
  109. ///////////////////////////////////////////////////////////////////////////////////////////
  110. int
  111. pcl::PCDReader::readHeader (const std::string &file_name, pcl::PCLPointCloud2 &cloud,
  112.                             Eigen::Vector4f &origin, Eigen::Quaternionf &orientation,
  113.                             int &pcd_version, int &data_type, unsigned int &data_idx, const int offset)
  114. {
  115.   // Default values
  116.   data_idx = 0;
  117.   data_type = 0;
  118.   pcd_version = PCD_V6;
  119.   origin      = Eigen::Vector4f::Zero ();
  120.   orientation = Eigen::Quaternionf::Identity ();
  121.   cloud.width = cloud.height = cloud.point_step = cloud.row_step = 0;
  122.   cloud.data.clear ();
  123.  
  124.   // By default, assume that there are _no_ invalid (e.g., NaN) points
  125.   //cloud.is_dense = true;
  126.  
  127.   int nr_points = 0;
  128.   std::ifstream fs;
  129.   std::string line;
  130.  
  131.   int specified_channel_count = 0;
  132.  
  133.   if (file_name == "" || !boost::filesystem::exists (file_name))
  134.   {
  135.     PCL_ERROR ("[pcl::PCDReader::readHeader] Could not find file '%s'.\n", file_name.c_str ());
  136.     return (-1);
  137.   }
  138.  
  139.   // Open file in binary mode to avoid problem of
  140.   // std::getline() corrupting the result of ifstream::tellg()
  141.   fs.open (file_name.c_str (), std::ios::binary);
  142.   if (!fs.is_open () || fs.fail ())
  143.   {
  144.     PCL_ERROR ("[pcl::PCDReader::readHeader] Could not open file '%s'! Error : %s\n", file_name.c_str (), strerror(errno));
  145.     fs.close ();
  146.     return (-1);
  147.   }
  148.  
  149.   // Seek at the given offset
  150.   fs.seekg (offset, std::ios::beg);
  151.  
  152.   // field_sizes represents the size of one element in a field (e.g., float = 4, char = 1)
  153.   // field_counts represents the number of elements in a field (e.g., x = 1, normal_x = 1, fpfh = 33)
  154.   std::vector<int> field_sizes, field_counts;
  155.   // field_types represents the type of data in a field (e.g., F = float, U = unsigned)
  156.   std::vector<char> field_types;
  157.   std::vector<std::string> st;
  158.  
  159.   // Read the header and fill it in with wonderful values
  160.   try
  161.   {
  162.     while (!fs.eof ())
  163.     {
  164.       getline (fs, line);
  165.       // Ignore empty lines
  166.       if (line == "")
  167.         continue;
  168.  
  169.       // Tokenize the line
  170.       boost::trim (line);
  171.       boost::split (st, line, boost::is_any_of ("\t\r "), boost::token_compress_on);
  172.  
  173.       std::stringstream sstream (line);
  174.       sstream.imbue (std::locale::classic ());
  175.  
  176.       std::string line_type;
  177.       sstream >> line_type;
  178.  
  179.       // Ignore comments
  180.       if (line_type.substr (0, 1) == "#")
  181.         continue;
  182.  
  183.       // Version numbers are not needed for now, but we are checking to see if they're there
  184.       if (line_type.substr (0, 7) == "VERSION")
  185.         continue;
  186.  
  187.       // Get the field indices (check for COLUMNS too for backwards compatibility)
  188.       if ( (line_type.substr (0, 6) == "FIELDS") || (line_type.substr (0, 7) == "COLUMNS") )
  189.       {
  190.         specified_channel_count = static_cast<int> (st.size () - 1);
  191.  
  192.         // Allocate enough memory to accommodate all fields
  193.         cloud.fields.resize (specified_channel_count);
  194.         for (int i = 0; i < specified_channel_count; ++i)
  195.         {
  196.           std::string col_type = st.at (i + 1);
  197.           cloud.fields[i].name = col_type;
  198.         }
  199.  
  200.         // Default the sizes and the types of each field to float32 to avoid crashes while using older PCD files
  201.         int offset = 0;
  202.         for (int i = 0; i < specified_channel_count; ++i, offset += 4)
  203.         {
  204.           cloud.fields[i].offset   = offset;
  205.           cloud.fields[i].datatype = pcl::PCLPointField::FLOAT32;
  206.           cloud.fields[i].count    = 1;
  207.         }
  208.         cloud.point_step = offset;
  209.         continue;
  210.       }
  211.  
  212.       // Get the field sizes
  213.       if (line_type.substr (0, 4) == "SIZE")
  214.       {
  215.         specified_channel_count = static_cast<int> (st.size () - 1);
  216.  
  217.         // Allocate enough memory to accommodate all fields
  218.         if (specified_channel_count != static_cast<int> (cloud.fields.size ()))
  219.           throw "The number of elements in <SIZE> differs than the number of elements in <FIELDS>!";
  220.  
  221.         // Resize to accommodate the number of values
  222.         field_sizes.resize (specified_channel_count);
  223.  
  224.         int offset = 0;
  225.         for (int i = 0; i < specified_channel_count; ++i)
  226.         {
  227.           int col_type ;
  228.           sstream >> col_type;
  229.           cloud.fields[i].offset = offset;                // estimate and save the data offsets
  230.           offset += col_type;
  231.           field_sizes[i] = col_type;                      // save a temporary copy
  232.         }
  233.         cloud.point_step = offset;
  234.         //if (cloud.width != 0)
  235.           //cloud.row_step   = cloud.point_step * cloud.width;
  236.         continue;
  237.       }
  238.  
  239.       // Get the field types
  240.       if (line_type.substr (0, 4) == "TYPE")
  241.       {
  242.         if (field_sizes.empty ())
  243.           throw "TYPE of FIELDS specified before SIZE in header!";
  244.  
  245.         specified_channel_count = static_cast<int> (st.size () - 1);
  246.  
  247.         // Allocate enough memory to accommodate all fields
  248.         if (specified_channel_count != static_cast<int> (cloud.fields.size ()))
  249.           throw "The number of elements in <TYPE> differs than the number of elements in <FIELDS>!";
  250.  
  251.         // Resize to accommodate the number of values
  252.         field_types.resize (specified_channel_count);
  253.  
  254.         for (int i = 0; i < specified_channel_count; ++i)
  255.         {
  256.           field_types[i] = st.at (i + 1).c_str ()[0];
  257.           cloud.fields[i].datatype = static_cast<uint8_t> (getFieldType (field_sizes[i], field_types[i]));
  258.         }
  259.         continue;
  260.       }
  261.  
  262.       // Get the field counts
  263.       if (line_type.substr (0, 5) == "COUNT")
  264.       {
  265.         if (field_sizes.empty () || field_types.empty ())
  266.           throw "COUNT of FIELDS specified before SIZE or TYPE in header!";
  267.  
  268.         specified_channel_count = static_cast<int> (st.size () - 1);
  269.  
  270.         // Allocate enough memory to accommodate all fields
  271.         if (specified_channel_count != static_cast<int> (cloud.fields.size ()))
  272.           throw "The number of elements in <COUNT> differs than the number of elements in <FIELDS>!";
  273.  
  274.         field_counts.resize (specified_channel_count);
  275.  
  276.         int offset = 0;
  277.         for (int i = 0; i < specified_channel_count; ++i)
  278.         {
  279.           cloud.fields[i].offset = offset;
  280.           int col_count;
  281.           sstream >> col_count;
  282.           cloud.fields[i].count = col_count;
  283.           offset += col_count * field_sizes[i];
  284.         }
  285.         // Adjust the offset for count (number of elements)
  286.         cloud.point_step = offset;
  287.         continue;
  288.       }
  289.  
  290.       // Get the width of the data (organized point cloud dataset)
  291.       if (line_type.substr (0, 5) == "WIDTH")
  292.       {
  293.         sstream >> cloud.width;
  294.         if (cloud.point_step != 0)
  295.           cloud.row_step = cloud.point_step * cloud.width;      // row_step only makes sense for organized datasets
  296.         continue;
  297.       }
  298.  
  299.       // Get the height of the data (organized point cloud dataset)
  300.       if (line_type.substr (0, 6) == "HEIGHT")
  301.       {
  302.         sstream >> cloud.height;
  303.         continue;
  304.       }
  305.  
  306.       // Get the acquisition viewpoint
  307.       if (line_type.substr (0, 9) == "VIEWPOINT")
  308.       {
  309.         pcd_version = PCD_V7;
  310.         if (st.size () < 8)
  311.           throw "Not enough number of elements in <VIEWPOINT>! Need 7 values (tx ty tz qw qx qy qz).";
  312.  
  313.         float x, y, z, w;
  314.         sstream >> x >> y >> z ;
  315.         origin      = Eigen::Vector4f (x, y, z, 0.0f);
  316.         sstream >> w >> x >> y >> z;
  317.         orientation = Eigen::Quaternionf (w, x, y, z);
  318.         continue;
  319.       }
  320.  
  321.       // Get the number of points
  322.       if (line_type.substr (0, 6) == "POINTS")
  323.       {
  324.         sstream >> nr_points;
  325.         // Need to allocate: N * point_step
  326.         cloud.data.resize (nr_points * cloud.point_step);
  327.         continue;
  328.       }
  329.  
  330.       // Read the header + comments line by line until we get to <DATA>
  331.       if (line_type.substr (0, 4) == "DATA")
  332.       {
  333.         data_idx = static_cast<int> (fs.tellg ());
  334.         if (st.at (1).substr (0, 17) == "binary_compressed")
  335.          data_type = 2;
  336.         else
  337.           if (st.at (1).substr (0, 6) == "binary")
  338.             data_type = 1;
  339.         continue;
  340.       }
  341.       break;
  342.     }
  343.   }
  344.   catch (const char *exception)
  345.   {
  346.     PCL_ERROR ("[pcl::PCDReader::readHeader] %s\n", exception);
  347.     fs.close ();
  348.     return (-1);
  349.   }
  350.  
  351.   // Exit early: if no points have been given, there's no sense to read or check anything anymore
  352.   if (nr_points == 0)
  353.   {
  354.     PCL_ERROR ("[pcl::PCDReader::readHeader] No points to read\n");
  355.     fs.close ();
  356.     return (-1);
  357.   }
  358.  
  359.   // Compatibility with older PCD file versions
  360.   if (cloud.width == 0 && cloud.height == 0)
  361.   {
  362.     cloud.width  = nr_points;
  363.     cloud.height = 1;
  364.     cloud.row_step = cloud.point_step * cloud.width;      // row_step only makes sense for organized datasets
  365.   }
  366.   //assert (cloud.row_step != 0);       // If row_step = 0, either point_step was not set or width is 0
  367.  
  368.   // if both height/width are not given, assume an unorganized dataset
  369.   if (cloud.height == 0)
  370.   {
  371.     cloud.height = 1;
  372.     PCL_WARN ("[pcl::PCDReader::readHeader] no HEIGHT given, setting to 1 (unorganized).\n");
  373.     if (cloud.width == 0)
  374.       cloud.width  = nr_points;
  375.   }
  376.   else
  377.   {
  378.     if (cloud.width == 0 && nr_points != 0)
  379.     {
  380.       PCL_ERROR ("[pcl::PCDReader::readHeader] HEIGHT given (%d) but no WIDTH!\n", cloud.height);
  381.       fs.close ();
  382.       return (-1);
  383.     }
  384.   }
  385.  
  386.   if (int (cloud.width * cloud.height) != nr_points)
  387.   {
  388.     PCL_ERROR ("[pcl::PCDReader::readHeader] HEIGHT (%d) x WIDTH (%d) != number of points (%d)\n", cloud.height, cloud.width, nr_points);
  389.     fs.close ();
  390.     return (-1);
  391.   }
  392.  
  393.   // Close file
  394.   fs.close ();
  395.  
  396.   return (0);
  397. }
  398.  
  399. ///////////////////////////////////////////////////////////////////////////////////////////
  400. int
  401. pcl::PCDReader::readHeader (const std::string &file_name, pcl::PCLPointCloud2 &cloud, const int offset)
  402. {
  403.   // Default values
  404.   cloud.width = cloud.height = cloud.point_step = cloud.row_step = 0;
  405.   cloud.data.clear ();
  406.  
  407.   // By default, assume that there are _no_ invalid (e.g., NaN) points
  408.   //cloud.is_dense = true;
  409.  
  410.   int nr_points = 0;
  411.   std::ifstream fs;
  412.   std::string line;
  413.  
  414.   int specified_channel_count = 0;
  415.  
  416.   if (file_name == "" || !boost::filesystem::exists (file_name))
  417.   {
  418.     PCL_ERROR ("[pcl::PCDReader::readHeader] Could not find file '%s'.\n", file_name.c_str ());
  419.     return (-1);
  420.   }
  421.  
  422.   // Open file in binary mode to avoid problem of
  423.   // std::getline() corrupting the result of ifstream::tellg()
  424.   fs.open (file_name.c_str (), std::ios::binary);
  425.   if (!fs.is_open () || fs.fail ())
  426.   {
  427.     PCL_ERROR ("[pcl::PCDReader::readHeader] Could not open file '%s'! Error : %s\n", file_name.c_str (), strerror(errno));
  428.     fs.close ();
  429.     return (-1);
  430.   }
  431.  
  432.   // Seek at the given offset
  433.   fs.seekg (offset, std::ios::beg);
  434.  
  435.   // field_sizes represents the size of one element in a field (e.g., float = 4, char = 1)
  436.   // field_counts represents the number of elements in a field (e.g., x = 1, normal_x = 1, fpfh = 33)
  437.   std::vector<int> field_sizes, field_counts;
  438.   // field_types represents the type of data in a field (e.g., F = float, U = unsigned)
  439.   std::vector<char> field_types;
  440.   std::vector<std::string> st;
  441.  
  442.   // Read the header and fill it in with wonderful values
  443.   try
  444.   {
  445.     while (!fs.eof ())
  446.     {
  447.       getline (fs, line);
  448.       // Ignore empty lines
  449.       if (line == "")
  450.         continue;
  451.  
  452.       // Tokenize the line
  453.       boost::trim (line);
  454.       boost::split (st, line, boost::is_any_of ("\t\r "), boost::token_compress_on);
  455.  
  456.       std::stringstream sstream (line);
  457.       sstream.imbue (std::locale::classic ());
  458.  
  459.       std::string line_type;
  460.       sstream >> line_type;
  461.  
  462.       // Ignore comments
  463.       if (line_type.substr (0, 1) == "#")
  464.         continue;
  465.  
  466.       // Version numbers are not needed for now, but we are checking to see if they're there
  467.       if (line_type.substr (0, 7) == "VERSION")
  468.         continue;
  469.  
  470.       // Get the field indices (check for COLUMNS too for backwards compatibility)
  471.       if ( (line_type.substr (0, 6) == "FIELDS") || (line_type.substr (0, 7) == "COLUMNS") )
  472.       {
  473.         specified_channel_count = static_cast<int> (st.size () - 1);
  474.  
  475.         // Allocate enough memory to accommodate all fields
  476.         cloud.fields.resize (specified_channel_count);
  477.         for (int i = 0; i < specified_channel_count; ++i)
  478.         {
  479.           std::string col_type = st.at (i + 1);
  480.           cloud.fields[i].name = col_type;
  481.         }
  482.  
  483.         // Default the sizes and the types of each field to float32 to avoid crashes while using older PCD files
  484.         int offset = 0;
  485.         for (int i = 0; i < specified_channel_count; ++i, offset += 4)
  486.         {
  487.           cloud.fields[i].offset   = offset;
  488.           cloud.fields[i].datatype = pcl::PCLPointField::FLOAT32;
  489.           cloud.fields[i].count    = 1;
  490.         }
  491.         cloud.point_step = offset;
  492.         continue;
  493.       }
  494.  
  495.       // Get the field sizes
  496.       if (line_type.substr (0, 4) == "SIZE")
  497.       {
  498.         specified_channel_count = static_cast<int> (st.size () - 1);
  499.  
  500.         // Allocate enough memory to accommodate all fields
  501.         if (specified_channel_count != static_cast<int> (cloud.fields.size ()))
  502.           throw "The number of elements in <SIZE> differs than the number of elements in <FIELDS>!";
  503.  
  504.         // Resize to accommodate the number of values
  505.         field_sizes.resize (specified_channel_count);
  506.  
  507.         int offset = 0;
  508.         for (int i = 0; i < specified_channel_count; ++i)
  509.         {
  510.           int col_type ;
  511.           sstream >> col_type;
  512.           cloud.fields[i].offset = offset;                // estimate and save the data offsets
  513.           offset += col_type;
  514.           field_sizes[i] = col_type;                      // save a temporary copy
  515.         }
  516.         cloud.point_step = offset;
  517.         //if (cloud.width != 0)
  518.           //cloud.row_step   = cloud.point_step * cloud.width;
  519.         continue;
  520.       }
  521.  
  522.       // Get the field types
  523.       if (line_type.substr (0, 4) == "TYPE")
  524.       {
  525.         if (field_sizes.empty ())
  526.           throw "TYPE of FIELDS specified before SIZE in header!";
  527.  
  528.         specified_channel_count = static_cast<int> (st.size () - 1);
  529.  
  530.         // Allocate enough memory to accommodate all fields
  531.         if (specified_channel_count != static_cast<int> (cloud.fields.size ()))
  532.           throw "The number of elements in <TYPE> differs than the number of elements in <FIELDS>!";
  533.  
  534.         // Resize to accommodate the number of values
  535.         field_types.resize (specified_channel_count);
  536.  
  537.         for (int i = 0; i < specified_channel_count; ++i)
  538.         {
  539.           field_types[i] = st.at (i + 1).c_str ()[0];
  540.           cloud.fields[i].datatype = static_cast<uint8_t> (getFieldType (field_sizes[i], field_types[i]));
  541.         }
  542.         continue;
  543.       }
  544.  
  545.       // Get the field counts
  546.       if (line_type.substr (0, 5) == "COUNT")
  547.       {
  548.         if (field_sizes.empty () || field_types.empty ())
  549.           throw "COUNT of FIELDS specified before SIZE or TYPE in header!";
  550.  
  551.         specified_channel_count = static_cast<int> (st.size () - 1);
  552.  
  553.         // Allocate enough memory to accommodate all fields
  554.         if (specified_channel_count != static_cast<int> (cloud.fields.size ()))
  555.           throw "The number of elements in <COUNT> differs than the number of elements in <FIELDS>!";
  556.  
  557.         field_counts.resize (specified_channel_count);
  558.  
  559.         int offset = 0;
  560.         for (int i = 0; i < specified_channel_count; ++i)
  561.         {
  562.           cloud.fields[i].offset = offset;
  563.           int col_count;
  564.           sstream >> col_count;
  565.           cloud.fields[i].count = col_count;
  566.           offset += col_count * field_sizes[i];
  567.         }
  568.         // Adjust the offset for count (number of elements)
  569.         cloud.point_step = offset;
  570.         continue;
  571.       }
  572.  
  573.       // Get the width of the data (organized point cloud dataset)
  574.       if (line_type.substr (0, 5) == "WIDTH")
  575.       {
  576.         sstream >> cloud.width;
  577.         if (cloud.point_step != 0)
  578.           cloud.row_step = cloud.point_step * cloud.width;      // row_step only makes sense for organized datasets
  579.         continue;
  580.       }
  581.  
  582.       // Get the height of the data (organized point cloud dataset)
  583.       if (line_type.substr (0, 6) == "HEIGHT")
  584.       {
  585.         sstream >> cloud.height;
  586.         continue;
  587.       }
  588.  
  589.       // Check the format of the acquisition viewpoint
  590.       if (line_type.substr (0, 9) == "VIEWPOINT")
  591.       {
  592.         if (st.size () < 8)
  593.           throw "Not enough number of elements in <VIEWPOINT>! Need 7 values (tx ty tz qw qx qy qz).";
  594.         continue;
  595.       }
  596.  
  597.       // Get the number of points
  598.       if (line_type.substr (0, 6) == "POINTS")
  599.       {
  600.         sstream >> nr_points;
  601.         // Need to allocate: N * point_step
  602.         cloud.data.resize (nr_points * cloud.point_step);
  603.         continue;
  604.       }
  605.       break;
  606.     }
  607.   }
  608.   catch (const char *exception)
  609.   {
  610.     PCL_ERROR ("[pcl::PCDReader::readHeader] %s\n", exception);
  611.     fs.close ();
  612.     return (-1);
  613.   }
  614.  
  615.   // Exit early: if no points have been given, there's no sense to read or check anything anymore
  616.   if (nr_points == 0)
  617.   {
  618.     PCL_ERROR ("[pcl::PCDReader::readHeader] No points to read\n");
  619.     fs.close ();
  620.     return (-1);
  621.   }
  622.  
  623.   // Compatibility with older PCD file versions
  624.   if (cloud.width == 0 && cloud.height == 0)
  625.   {
  626.     cloud.width  = nr_points;
  627.     cloud.height = 1;
  628.     cloud.row_step = cloud.point_step * cloud.width;      // row_step only makes sense for organized datasets
  629.   }
  630.   //assert (cloud.row_step != 0);       // If row_step = 0, either point_step was not set or width is 0
  631.  
  632.   // if both height/width are not given, assume an unorganized dataset
  633.   if (cloud.height == 0)
  634.   {
  635.     cloud.height = 1;
  636.     PCL_WARN ("[pcl::PCDReader::readHeader] no HEIGHT given, setting to 1 (unorganized).\n");
  637.     if (cloud.width == 0)
  638.       cloud.width  = nr_points;
  639.   }
  640.   else
  641.   {
  642.     if (cloud.width == 0 && nr_points != 0)
  643.     {
  644.       PCL_ERROR ("[pcl::PCDReader::readHeader] HEIGHT given (%d) but no WIDTH!\n", cloud.height);
  645.       fs.close ();
  646.       return (-1);
  647.     }
  648.   }
  649.  
  650.   if (int (cloud.width * cloud.height) != nr_points)
  651.   {
  652.     PCL_ERROR ("[pcl::PCDReader::readHeader] HEIGHT (%d) x WIDTH (%d) != number of points (%d)\n", cloud.height, cloud.width, nr_points);
  653.     fs.close ();
  654.     return (-1);
  655.   }
  656.  
  657.   // Close file
  658.   fs.close ();
  659.  
  660.   return (0);
  661. }
  662.  
  663. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  664. int
  665. pcl::PCDReader::read (const std::string &file_name, pcl::PCLPointCloud2 &cloud,
  666.                       Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, int &pcd_version,
  667.                       const int offset)
  668. {
  669.   pcl::console::TicToc tt;
  670.   tt.tic ();
  671.  
  672.   int data_type;
  673.   unsigned int data_idx;
  674.  
  675.   int res = readHeader (file_name, cloud, origin, orientation, pcd_version, data_type, data_idx, offset);
  676.  
  677.   if (res < 0)
  678.     return (res);
  679.  
  680.   unsigned int idx = 0;
  681.  
  682.   // Get the number of points the cloud should have
  683.   unsigned int nr_points = cloud.width * cloud.height;
  684.  
  685.   // Setting the is_dense property to true by default
  686.   cloud.is_dense = true;
  687.  
  688.   if (file_name == "" || !boost::filesystem::exists (file_name))
  689.   {
  690.     PCL_ERROR ("[pcl::PCDReader::read] Could not find file '%s'.\n", file_name.c_str ());
  691.     return (-1);
  692.   }
  693.  
  694.   // if ascii
  695.   if (data_type == 0)
  696.   {
  697.     // Re-open the file (readHeader closes it)
  698.     std::ifstream fs;
  699.     fs.open (file_name.c_str ());
  700.     if (!fs.is_open () || fs.fail ())
  701.     {
  702.       PCL_ERROR ("[pcl::PCDReader::read] Could not open file %s.\n", file_name.c_str ());
  703.       return (-1);
  704.     }
  705.  
  706.     fs.seekg (data_idx);
  707.  
  708.     std::string line;
  709.     std::vector<std::string> st;
  710.  
  711.     // Read the rest of the file
  712.     try
  713.     {
  714.       while (idx < nr_points && !fs.eof ())
  715.       {
  716.         getline (fs, line);
  717.         // Ignore empty lines
  718.         if (line == "")
  719.           continue;
  720.  
  721.         // Tokenize the line
  722.         boost::trim (line);
  723.         boost::split (st, line, boost::is_any_of ("\t\r "), boost::token_compress_on);
  724.        
  725.         if (idx >= nr_points)
  726.         {
  727.           PCL_WARN ("[pcl::PCDReader::read] input file %s has more points (%d) than advertised (%d)!\n", file_name.c_str (), idx, nr_points);
  728.           break;
  729.         }
  730.  
  731.         size_t total = 0;
  732.         // Copy data
  733.         for (unsigned int d = 0; d < static_cast<unsigned int> (cloud.fields.size ()); ++d)
  734.         {
  735.           // Ignore invalid padded dimensions that are inherited from binary data
  736.           if (cloud.fields[d].name == "_")
  737.           {
  738.             total += cloud.fields[d].count; // jump over this many elements in the string token
  739.             continue;
  740.           }
  741.           for (unsigned int c = 0; c < cloud.fields[d].count; ++c)
  742.           {
  743.             switch (cloud.fields[d].datatype)
  744.             {
  745.               case pcl::PCLPointField::INT8:
  746.               {
  747.                 copyStringValue<pcl::traits::asType<pcl::PCLPointField::INT8>::type> (
  748.                     st.at (total + c), cloud, idx, d, c);
  749.                 break;
  750.               }
  751.               case pcl::PCLPointField::UINT8:
  752.               {
  753.                 copyStringValue<pcl::traits::asType<pcl::PCLPointField::UINT8>::type> (
  754.                     st.at (total + c), cloud, idx, d, c);
  755.                 break;
  756.               }
  757.               case pcl::PCLPointField::INT16:
  758.               {
  759.                 copyStringValue<pcl::traits::asType<pcl::PCLPointField::INT16>::type> (
  760.                     st.at (total + c), cloud, idx, d, c);
  761.                 break;
  762.               }
  763.               case pcl::PCLPointField::UINT16:
  764.               {
  765.                 copyStringValue<pcl::traits::asType<pcl::PCLPointField::UINT16>::type> (
  766.                     st.at (total + c), cloud, idx, d, c);
  767.                 break;
  768.               }
  769.               case pcl::PCLPointField::INT32:
  770.               {
  771.                 copyStringValue<pcl::traits::asType<pcl::PCLPointField::INT32>::type> (
  772.                     st.at (total + c), cloud, idx, d, c);
  773.                 break;
  774.               }
  775.               case pcl::PCLPointField::UINT32:
  776.               {
  777.                 copyStringValue<pcl::traits::asType<pcl::PCLPointField::UINT32>::type> (
  778.                     st.at (total + c), cloud, idx, d, c);
  779.                 break;
  780.               }
  781.               case pcl::PCLPointField::FLOAT32:
  782.               {
  783.                 copyStringValue<pcl::traits::asType<pcl::PCLPointField::FLOAT32>::type> (
  784.                     st.at (total + c), cloud, idx, d, c);
  785.                 break;
  786.               }
  787.               case pcl::PCLPointField::FLOAT64:
  788.               {
  789.                 copyStringValue<pcl::traits::asType<pcl::PCLPointField::FLOAT64>::type> (
  790.                     st.at (total + c), cloud, idx, d, c);
  791.                 break;
  792.               }
  793.               default:
  794.                 PCL_WARN ("[pcl::PCDReader::read] Incorrect field data type specified (%d)!\n",cloud.fields[d].datatype);
  795.                 break;
  796.             }
  797.           }
  798.           total += cloud.fields[d].count; // jump over this many elements in the string token
  799.         }
  800.         idx++;
  801.       }
  802.     }
  803.     catch (const char *exception)
  804.     {
  805.       PCL_ERROR ("[pcl::PCDReader::read] %s\n", exception);
  806.       fs.close ();
  807.       return (-1);
  808.     }
  809.  
  810.     // Close file
  811.     fs.close ();
  812.   }
  813.   else
  814.   /// ---[ Binary mode only
  815.   /// We must re-open the file and read with mmap () for binary
  816.   {
  817.     // Open for reading
  818.     int fd = pcl_open (file_name.c_str (), O_RDONLY);
  819.     if (fd == -1)
  820.     {
  821.       PCL_ERROR ("[pcl::PCDReader::read] Failure to open file %s\n", file_name.c_str () );
  822.       return (-1);
  823.     }
  824.    
  825.     // Seek at the given offset
  826.     off_t result = pcl_lseek (fd, offset, SEEK_SET);
  827.     if (result < 0)
  828.     {
  829.       pcl_close (fd);
  830.       PCL_ERROR ("[pcl::PCDReader::read] lseek errno: %d strerror: %s\n", errno, strerror (errno));
  831.       PCL_ERROR ("[pcl::PCDReader::read] Error during lseek ()!\n");
  832.       return (-1);
  833.     }
  834.    
  835.     size_t data_size = data_idx + cloud.data.size ();
  836.     // Prepare the map
  837. #ifdef _WIN32
  838.     // As we don't know the real size of data (compressed or not),
  839.     // we set dwMaximumSizeHigh = dwMaximumSizeLow = 0 so as to map the whole file
  840.     HANDLE fm = CreateFileMapping ((HANDLE) _get_osfhandle (fd), NULL, PAGE_READONLY, 0, 0, NULL);
  841.     // As we don't know the real size of data (compressed or not),
  842.     // we set dwNumberOfBytesToMap = 0 so as to map the whole file
  843.     char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ, 0, 0, 0));
  844.     if (map == NULL)
  845.     {
  846.       CloseHandle (fm);
  847.       pcl_close (fd);
  848.       PCL_ERROR ("[pcl::PCDReader::read] Error mapping view of file, %s\n", file_name.c_str ());
  849.       return (-1);
  850.     }
  851. #else
  852.     char *map = static_cast<char*> (mmap (0, data_size, PROT_READ, MAP_SHARED, fd, 0));
  853.     if (map == reinterpret_cast<char*> (-1))    // MAP_FAILED
  854.     {
  855.       pcl_close (fd);
  856.       PCL_ERROR ("[pcl::PCDReader::read] Error preparing mmap for binary PCD file.\n");
  857.       return (-1);
  858.     }
  859. #endif
  860.  
  861.     /// ---[ Binary compressed mode only
  862.     if (data_type == 2)
  863.     {
  864.       // Uncompress the data first
  865.       unsigned int compressed_size, uncompressed_size;
  866.       memcpy (&compressed_size, &map[data_idx + 0], sizeof (unsigned int));
  867.       memcpy (&uncompressed_size, &map[data_idx + 4], sizeof (unsigned int));
  868.       PCL_DEBUG ("[pcl::PCDReader::read] Read a binary compressed file with %u bytes compressed and %u original.\n", compressed_size, uncompressed_size);
  869.       // For all those weird situations where the compressed data is actually LARGER than the uncompressed one
  870.       // (we really ought to check this in the compressor and copy the original data in those cases)
  871.       if (data_size < compressed_size || uncompressed_size < compressed_size)
  872.       {
  873.         PCL_DEBUG ("[pcl::PCDReader::read] Allocated data size (%lu) or uncompressed size (%lu) smaller than compressed size (%u). Need to remap.\n", data_size, uncompressed_size, compressed_size);
  874. #ifdef _WIN32
  875.         UnmapViewOfFile (map);
  876.         data_size = compressed_size + data_idx + 8;
  877.         map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ, 0, 0, data_size));
  878. #else
  879.         munmap (map, data_size);
  880.         data_size = compressed_size + data_idx + 8;
  881.         map = static_cast<char*> (mmap (0, data_size, PROT_READ, MAP_SHARED, fd, 0));
  882. #endif
  883.       }
  884.  
  885.       if (uncompressed_size != cloud.data.size ())
  886.       {
  887.         PCL_WARN ("[pcl::PCDReader::read] The estimated cloud.data size (%u) is different than the saved uncompressed value (%u)! Data corruption?\n",
  888.                   cloud.data.size (), uncompressed_size);
  889.         cloud.data.resize (uncompressed_size);
  890.       }
  891.       //char *buf = new static_cast<char*> (data_size);//change yamamoto
  892.       char *buf = static_cast<char*> (malloc (data_size));
  893.       assert(buf == NULL);
  894.       // The size of the uncompressed data better be the same as what we stored in the header
  895.       unsigned int tmp_size = pcl::lzfDecompress (&map[data_idx + 8], compressed_size, buf, static_cast<unsigned int> (data_size));
  896.       if (tmp_size != uncompressed_size)
  897.       {
  898.         free (buf);
  899.         buf=NULL;
  900.         pcl_close (fd);
  901.         PCL_ERROR ("[pcl::PCDReader::read] Size of decompressed lzf data (%u) does not match value stored in PCD header (%u). Errno: %d\n", tmp_size, uncompressed_size, errno);
  902.         return (-1);
  903.       }
  904.  
  905.       // Get the fields sizes
  906.       std::vector<pcl::PCLPointField> fields (cloud.fields.size ());
  907.       std::vector<int> fields_sizes (cloud.fields.size ());
  908.       int nri = 0, fsize = 0;
  909.       for (size_t i = 0; i < cloud.fields.size (); ++i)
  910.       {
  911.         if (cloud.fields[i].name == "_")
  912.           continue;
  913.         fields_sizes[nri] = cloud.fields[i].count * pcl::getFieldSize (cloud.fields[i].datatype);
  914.         fsize += fields_sizes[nri];
  915.         fields[nri] = cloud.fields[i];
  916.         ++nri;
  917.       }
  918.       fields.resize (nri);
  919.       fields_sizes.resize (nri);
  920.  
  921.       // Unpack the xxyyzz to xyz
  922.       std::vector<char*> pters (fields.size ());
  923.       int toff = 0;
  924.       for (size_t i = 0; i < pters.size (); ++i)
  925.       {
  926.         pters[i] = &buf[toff];
  927.         toff += fields_sizes[i] * cloud.width * cloud.height;
  928.       }
  929.       // Copy it to the cloud
  930.       for (size_t i = 0; i < cloud.width * cloud.height; ++i)
  931.       {
  932.         for (size_t j = 0; j < pters.size (); ++j)
  933.         {
  934.           memcpy (&cloud.data[i * fsize + fields[j].offset], pters[j], fields_sizes[j]);
  935.           // Increment the pointer
  936.           pters[j] += fields_sizes[j];
  937.         }
  938.       }
  939.       //memcpy (&cloud.data[0], &buf[0], uncompressed_size);
  940.  
  941.       free (buf);
  942.       buf=NULL;
  943.     }
  944.     else
  945.       // Copy the data
  946.       memcpy (&cloud.data[0], &map[0] + data_idx, cloud.data.size ());
  947.  
  948.     // Unmap the pages of memory
  949. #ifdef _WIN32
  950.     UnmapViewOfFile (map);
  951.     CloseHandle (fm);
  952. #else
  953.     if (munmap (map, data_size) == -1)
  954.     {
  955.       pcl_close (fd);
  956.       PCL_ERROR ("[pcl::PCDReader::read] Munmap failure\n");
  957.       return (-1);
  958.     }
  959. #endif
  960.     pcl_close (fd);
  961.   }
  962.  
  963.   if ((idx != nr_points) && (data_type == 0))
  964.   {
  965.     PCL_ERROR ("[pcl::PCDReader::read] Number of points read (%d) is different than expected (%d)\n", idx, nr_points);
  966.     return (-1);
  967.   }
  968.  
  969.   // No need to do any extra checks if the data type is ASCII
  970.   if (data_type != 0)
  971.   {
  972.     int point_size = static_cast<int> (cloud.data.size () / (cloud.height * cloud.width));
  973.     // Once copied, we need to go over each field and check if it has NaN/Inf values and assign cloud.is_dense to true or false
  974.     for (uint32_t i = 0; i < cloud.width * cloud.height; ++i)
  975.     {
  976.       for (unsigned int d = 0; d < static_cast<unsigned int> (cloud.fields.size ()); ++d)
  977.       {
  978.         for (uint32_t c = 0; c < cloud.fields[d].count; ++c)
  979.         {
  980.           switch (cloud.fields[d].datatype)
  981.           {
  982.             case pcl::PCLPointField::INT8:
  983.             {
  984.               if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::INT8>::type>(cloud, i, point_size, d, c))
  985.                 cloud.is_dense = false;
  986.               break;
  987.             }
  988.             case pcl::PCLPointField::UINT8:
  989.             {
  990.               if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::UINT8>::type>(cloud, i, point_size, d, c))
  991.                 cloud.is_dense = false;
  992.               break;
  993.             }
  994.             case pcl::PCLPointField::INT16:
  995.             {
  996.               if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::INT16>::type>(cloud, i, point_size, d, c))
  997.                 cloud.is_dense = false;
  998.               break;
  999.             }
  1000.             case pcl::PCLPointField::UINT16:
  1001.             {
  1002.               if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::UINT16>::type>(cloud, i, point_size, d, c))
  1003.                 cloud.is_dense = false;
  1004.               break;
  1005.             }
  1006.             case pcl::PCLPointField::INT32:
  1007.             {
  1008.               if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::INT32>::type>(cloud, i, point_size, d, c))
  1009.                 cloud.is_dense = false;
  1010.               break;
  1011.             }
  1012.             case pcl::PCLPointField::UINT32:
  1013.             {
  1014.               if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::UINT32>::type>(cloud, i, point_size, d, c))
  1015.                 cloud.is_dense = false;
  1016.               break;
  1017.             }
  1018.             case pcl::PCLPointField::FLOAT32:
  1019.             {
  1020.               if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::FLOAT32>::type>(cloud, i, point_size, d, c))
  1021.                 cloud.is_dense = false;
  1022.               break;
  1023.             }
  1024.             case pcl::PCLPointField::FLOAT64:
  1025.             {
  1026.               if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::FLOAT64>::type>(cloud, i, point_size, d, c))
  1027.                 cloud.is_dense = false;
  1028.               break;
  1029.             }
  1030.           }
  1031.         }
  1032.       }
  1033.     }
  1034.   }
  1035.   double total_time = tt.toc ();
  1036.   PCL_DEBUG ("[pcl::PCDReader::read] Loaded %s as a %s cloud in %g ms with %d points. Available dimensions: %s.\n",
  1037.              file_name.c_str (), cloud.is_dense ? "dense" : "non-dense", total_time,
  1038.              cloud.width * cloud.height, pcl::getFieldsList (cloud).c_str ());
  1039.   return (0);
  1040. }
  1041.  
  1042. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1043. int
  1044. pcl::PCDReader::read (const std::string &file_name, pcl::PCLPointCloud2 &cloud, const int offset)
  1045. {
  1046.   int pcd_version;
  1047.   Eigen::Vector4f origin;
  1048.   Eigen::Quaternionf orientation;
  1049.   // Load the data
  1050.   int res = read (file_name, cloud, origin, orientation, pcd_version, offset);
  1051.  
  1052.   if (res < 0)
  1053.     return (res);
  1054.  
  1055.   return (0);
  1056. }
  1057.  
  1058. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1059. std::string
  1060. pcl::PCDWriter::generateHeaderASCII (const pcl::PCLPointCloud2 &cloud,
  1061.                                      const Eigen::Vector4f &origin, const Eigen::Quaternionf &orientation)
  1062. {
  1063.   std::ostringstream oss;
  1064.   oss.imbue (std::locale::classic ());
  1065.  
  1066.   oss << "# .PCD v0.7 - Point Cloud Data file format"
  1067.          "\nVERSION 0.7"
  1068.          "\nFIELDS ";
  1069.  
  1070.   std::ostringstream stream;
  1071.   stream.imbue (std::locale::classic ());
  1072.   std::string result;
  1073.  
  1074.   for (size_t d = 0; d < cloud.fields.size () - 1; ++d)
  1075.   {
  1076.     // Ignore invalid padded dimensions that are inherited from binary data
  1077.     if (cloud.fields[d].name != "_")
  1078.       result += cloud.fields[d].name + " ";
  1079.   }
  1080.   // Ignore invalid padded dimensions that are inherited from binary data
  1081.   if (cloud.fields[cloud.fields.size () - 1].name != "_")
  1082.     result += cloud.fields[cloud.fields.size () - 1].name;
  1083.  
  1084.   // Remove trailing spaces
  1085.   boost::trim (result);
  1086.   oss << result << "\nSIZE ";
  1087.  
  1088.   stream.str ("");
  1089.   // Write the SIZE of each field
  1090.   for (size_t d = 0; d < cloud.fields.size () - 1; ++d)
  1091.   {
  1092.     // Ignore invalid padded dimensions that are inherited from binary data
  1093.     if (cloud.fields[d].name != "_")
  1094.       stream << pcl::getFieldSize (cloud.fields[d].datatype) << " ";
  1095.   }
  1096.   // Ignore invalid padded dimensions that are inherited from binary data
  1097.   if (cloud.fields[cloud.fields.size () - 1].name != "_")
  1098.     stream << pcl::getFieldSize (cloud.fields[cloud.fields.size () - 1].datatype);
  1099.  
  1100.   // Remove trailing spaces
  1101.   result = stream.str ();
  1102.   boost::trim (result);
  1103.   oss << result << "\nTYPE ";
  1104.  
  1105.   stream.str ("");
  1106.   // Write the TYPE of each field
  1107.   for (size_t d = 0; d < cloud.fields.size () - 1; ++d)
  1108.   {
  1109.     // Ignore invalid padded dimensions that are inherited from binary data
  1110.     if (cloud.fields[d].name != "_")
  1111.       stream << pcl::getFieldType (cloud.fields[d].datatype) << " ";
  1112.   }
  1113.   // Ignore invalid padded dimensions that are inherited from binary data
  1114.   if (cloud.fields[cloud.fields.size () - 1].name != "_")
  1115.     stream << pcl::getFieldType (cloud.fields[cloud.fields.size () - 1].datatype);
  1116.  
  1117.   // Remove trailing spaces
  1118.   result = stream.str ();
  1119.   boost::trim (result);
  1120.   oss << result << "\nCOUNT ";
  1121.  
  1122.   stream.str ("");
  1123.   // Write the TYPE of each field
  1124.   for (size_t d = 0; d < cloud.fields.size () - 1; ++d)
  1125.   {
  1126.     // Ignore invalid padded dimensions that are inherited from binary data
  1127.     if (cloud.fields[d].name == "_")
  1128.       continue;
  1129.     int count = abs (static_cast<int> (cloud.fields[d].count));
  1130.     if (count == 0)
  1131.       count = 1;          // we simply cannot tolerate 0 counts (coming from older converter code)
  1132.  
  1133.     stream << count << " ";
  1134.   }
  1135.   // Ignore invalid padded dimensions that are inherited from binary data
  1136.   if (cloud.fields[cloud.fields.size () - 1].name != "_")
  1137.   {
  1138.     int count = abs (static_cast<int> (cloud.fields[cloud.fields.size () - 1].count));
  1139.     if (count == 0)
  1140.       count = 1;
  1141.  
  1142.     stream << count;
  1143.   }
  1144.  
  1145.   // Remove trailing spaces
  1146.   result = stream.str ();
  1147.   boost::trim (result);
  1148.   oss << result << "\nWIDTH " << cloud.width << "\nHEIGHT " << cloud.height << "\n";
  1149.  
  1150.   oss << "VIEWPOINT " << origin[0] << " " << origin[1] << " " << origin[2] << " " << orientation.w () << " " <<
  1151.                          orientation.x () << " " << orientation.y () << " " << orientation.z () << "\n";
  1152.  
  1153.   oss << "POINTS " << cloud.width * cloud.height << "\n";
  1154.  
  1155.   return (oss.str ());
  1156. }
  1157.  
  1158. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1159. std::string
  1160. pcl::PCDWriter::generateHeaderBinary (const pcl::PCLPointCloud2 &cloud,
  1161.                                       const Eigen::Vector4f &origin, const Eigen::Quaternionf &orientation)
  1162. {
  1163.   std::ostringstream oss;
  1164.   oss.imbue (std::locale::classic ());
  1165.  
  1166.   oss << "# .PCD v0.7 - Point Cloud Data file format"
  1167.          "\nVERSION 0.7"
  1168.          "\nFIELDS";
  1169.  
  1170.   // Compute the total size of the fields
  1171.   unsigned int fsize = 0;
  1172.   for (size_t i = 0; i < cloud.fields.size (); ++i)
  1173.     fsize += cloud.fields[i].count * getFieldSize (cloud.fields[i].datatype);
  1174.  
  1175.   // The size of the fields cannot be larger than point_step
  1176.   if (fsize > cloud.point_step)
  1177.   {
  1178.     PCL_ERROR ("[pcl::PCDWriter::generateHeaderBinary] The size of the fields (%d) is larger than point_step (%d)! Something is wrong here...\n", fsize, cloud.point_step);
  1179.     return ("");
  1180.   }
  1181.  
  1182.   std::stringstream field_names, field_types, field_sizes, field_counts;
  1183.   // Check if the size of the fields is smaller than the size of the point step
  1184.   unsigned int toffset = 0;
  1185.   for (size_t i = 0; i < cloud.fields.size (); ++i)
  1186.   {
  1187.     // If field offsets do not match, then we need to create fake fields
  1188.     if (toffset != cloud.fields[i].offset)
  1189.     {
  1190.       // If we're at the last "valid" field
  1191.       int fake_offset = (i == 0) ?
  1192.         // Use the current_field offset
  1193.         (cloud.fields[i].offset)
  1194.         :
  1195.         // Else, do cur_field.offset - prev_field.offset + sizeof (prev_field)
  1196.         (cloud.fields[i].offset -
  1197.         (cloud.fields[i-1].offset +
  1198.          cloud.fields[i-1].count * getFieldSize (cloud.fields[i].datatype)));
  1199.      
  1200.       toffset += fake_offset;
  1201.  
  1202.       field_names << " _";  // By convention, _ is an invalid field name
  1203.       field_sizes << " 1";  // Make size = 1
  1204.       field_types << " U";  // Field type = unsigned byte (uint8)
  1205.       field_counts << " " << fake_offset;
  1206.     }
  1207.  
  1208.     // Add the regular dimension
  1209.     toffset += cloud.fields[i].count * getFieldSize (cloud.fields[i].datatype);
  1210.     field_names << " " << cloud.fields[i].name;
  1211.     field_sizes << " " << pcl::getFieldSize (cloud.fields[i].datatype);
  1212.     field_types << " " << pcl::getFieldType (cloud.fields[i].datatype);
  1213.     int count = abs (static_cast<int> (cloud.fields[i].count));
  1214.     if (count == 0) count = 1;  // check for 0 counts (coming from older converter code)
  1215.     field_counts << " " << count;
  1216.   }
  1217.   // Check extra padding
  1218.   if (toffset < cloud.point_step)
  1219.   {
  1220.     field_names << " _";  // By convention, _ is an invalid field name
  1221.     field_sizes << " 1";  // Make size = 1
  1222.     field_types << " U";  // Field type = unsigned byte (uint8)
  1223.     field_counts << " " << (cloud.point_step - toffset);
  1224.   }
  1225.   oss << field_names.str ();
  1226.   oss << "\nSIZE" << field_sizes.str ()
  1227.       << "\nTYPE" << field_types.str ()
  1228.       << "\nCOUNT" << field_counts.str ();
  1229.   oss << "\nWIDTH " << cloud.width << "\nHEIGHT " << cloud.height << "\n";
  1230.  
  1231.   oss << "VIEWPOINT " << origin[0] << " " << origin[1] << " " << origin[2] << " " << orientation.w () << " " <<
  1232.                          orientation.x () << " " << orientation.y () << " " << orientation.z () << "\n";
  1233.  
  1234.   oss << "POINTS " << cloud.width * cloud.height << "\n";
  1235.  
  1236.   return (oss.str ());
  1237. }
  1238.  
  1239. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1240. std::string
  1241. pcl::PCDWriter::generateHeaderBinaryCompressed (const pcl::PCLPointCloud2 &cloud,
  1242.                                                 const Eigen::Vector4f &origin,
  1243.                                                 const Eigen::Quaternionf &orientation)
  1244. {
  1245.   std::ostringstream oss;
  1246.   oss.imbue (std::locale::classic ());
  1247.  
  1248.   oss << "# .PCD v0.7 - Point Cloud Data file format"
  1249.          "\nVERSION 0.7"
  1250.          "\nFIELDS";
  1251.  
  1252.   // Compute the total size of the fields
  1253.   unsigned int fsize = 0;
  1254.   for (size_t i = 0; i < cloud.fields.size (); ++i)
  1255.     fsize += cloud.fields[i].count * getFieldSize (cloud.fields[i].datatype);
  1256.  
  1257.   // The size of the fields cannot be larger than point_step
  1258.   if (fsize > cloud.point_step)
  1259.   {
  1260.     PCL_ERROR ("[pcl::PCDWriter::generateHeaderBinaryCompressed] The size of the fields (%d) is larger than point_step (%d)! Something is wrong here...\n", fsize, cloud.point_step);
  1261.     return ("");
  1262.   }
  1263.  
  1264.   std::stringstream field_names, field_types, field_sizes, field_counts;
  1265.   // Check if the size of the fields is smaller than the size of the point step
  1266.   for (size_t i = 0; i < cloud.fields.size (); ++i)
  1267.   {
  1268.     if (cloud.fields[i].name == "_")
  1269.       continue;
  1270.     // Add the regular dimension
  1271.     field_names << " " << cloud.fields[i].name;
  1272.     field_sizes << " " << pcl::getFieldSize (cloud.fields[i].datatype);
  1273.     field_types << " " << pcl::getFieldType (cloud.fields[i].datatype);
  1274.     int count = abs (static_cast<int> (cloud.fields[i].count));
  1275.     if (count == 0) count = 1;  // check for 0 counts (coming from older converter code)
  1276.     field_counts << " " << count;
  1277.   }
  1278.   oss << field_names.str ();
  1279.   oss << "\nSIZE" << field_sizes.str ()
  1280.       << "\nTYPE" << field_types.str ()
  1281.       << "\nCOUNT" << field_counts.str ();
  1282.   oss << "\nWIDTH " << cloud.width << "\nHEIGHT " << cloud.height << "\n";
  1283.  
  1284.   oss << "VIEWPOINT " << origin[0] << " " << origin[1] << " " << origin[2] << " " << orientation.w () << " " <<
  1285.                          orientation.x () << " " << orientation.y () << " " << orientation.z () << "\n";
  1286.  
  1287.   oss << "POINTS " << cloud.width * cloud.height << "\n";
  1288.  
  1289.   return (oss.str ());
  1290. }
  1291.  
  1292. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1293. int
  1294. pcl::PCDWriter::writeASCII (const std::string &file_name, const pcl::PCLPointCloud2 &cloud,
  1295.                             const Eigen::Vector4f &origin, const Eigen::Quaternionf &orientation,
  1296.                             const int precision)
  1297. {
  1298.   if (cloud.data.empty ())
  1299.   {
  1300.     PCL_ERROR ("[pcl::PCDWriter::writeASCII] Input point cloud has no data!\n");
  1301.     return (-1);
  1302.   }
  1303.  
  1304.   std::ofstream fs;
  1305.   fs.precision (precision);
  1306.   fs.imbue (std::locale::classic ());
  1307.   fs.open (file_name.c_str ());      // Open file
  1308.   if (!fs.is_open () || fs.fail ())
  1309.   {
  1310.     PCL_ERROR("[pcl::PCDWriter::writeASCII] Could not open file '%s' for writing! Error : %s\n", file_name.c_str (), strerror(errno));
  1311.     return (-1);
  1312.   }
  1313.   // Mandatory lock file
  1314.   boost::interprocess::file_lock file_lock;
  1315.   setLockingPermissions (file_name, file_lock);
  1316.  
  1317.   int nr_points  = cloud.width * cloud.height;
  1318.   int point_size = static_cast<int> (cloud.data.size () / nr_points);
  1319.  
  1320.   // Write the header information
  1321.   fs << generateHeaderASCII (cloud, origin, orientation) << "DATA ascii\n";
  1322.  
  1323.   std::ostringstream stream;
  1324.   stream.precision (precision);
  1325.   stream.imbue (std::locale::classic ());
  1326.  
  1327.   // Iterate through the points
  1328.   for (int i = 0; i < nr_points; ++i)
  1329.   {
  1330.     for (unsigned int d = 0; d < static_cast<unsigned int> (cloud.fields.size ()); ++d)
  1331.     {
  1332.       // Ignore invalid padded dimensions that are inherited from binary data
  1333.       if (cloud.fields[d].name == "_")
  1334.         continue;
  1335.  
  1336.       int count = cloud.fields[d].count;
  1337.       if (count == 0)
  1338.         count = 1;          // we simply cannot tolerate 0 counts (coming from older converter code)
  1339.  
  1340.       for (int c = 0; c < count; ++c)
  1341.       {
  1342.         switch (cloud.fields[d].datatype)
  1343.         {
  1344.           case pcl::PCLPointField::INT8:
  1345.           {
  1346.             copyValueString<pcl::traits::asType<pcl::PCLPointField::INT8>::type>(cloud, i, point_size, d, c, stream);
  1347.             break;
  1348.           }
  1349.           case pcl::PCLPointField::UINT8:
  1350.           {
  1351.             copyValueString<pcl::traits::asType<pcl::PCLPointField::UINT8>::type>(cloud, i, point_size, d, c, stream);
  1352.             break;
  1353.           }
  1354.           case pcl::PCLPointField::INT16:
  1355.           {
  1356.             copyValueString<pcl::traits::asType<pcl::PCLPointField::INT16>::type>(cloud, i, point_size, d, c, stream);
  1357.             break;
  1358.           }
  1359.           case pcl::PCLPointField::UINT16:
  1360.           {
  1361.             copyValueString<pcl::traits::asType<pcl::PCLPointField::UINT16>::type>(cloud, i, point_size, d, c, stream);
  1362.             break;
  1363.           }
  1364.           case pcl::PCLPointField::INT32:
  1365.           {
  1366.             copyValueString<pcl::traits::asType<pcl::PCLPointField::INT32>::type>(cloud, i, point_size, d, c, stream);
  1367.             break;
  1368.           }
  1369.           case pcl::PCLPointField::UINT32:
  1370.           {
  1371.             copyValueString<pcl::traits::asType<pcl::PCLPointField::UINT32>::type>(cloud, i, point_size, d, c, stream);
  1372.             break;
  1373.           }
  1374.           case pcl::PCLPointField::FLOAT32:
  1375.           {
  1376.             copyValueString<pcl::traits::asType<pcl::PCLPointField::FLOAT32>::type>(cloud, i, point_size, d, c, stream);
  1377.             break;
  1378.           }
  1379.           case pcl::PCLPointField::FLOAT64:
  1380.           {
  1381.             copyValueString<pcl::traits::asType<pcl::PCLPointField::FLOAT64>::type>(cloud, i, point_size, d, c, stream);
  1382.             break;
  1383.           }
  1384.           default:
  1385.             PCL_WARN ("[pcl::PCDWriter::writeASCII] Incorrect field data type specified (%d)!\n", cloud.fields[d].datatype);
  1386.             break;
  1387.         }
  1388.  
  1389.         if (d < cloud.fields.size () - 1 || c < static_cast<int> (cloud.fields[d].count) - 1)
  1390.           stream << " ";
  1391.       }
  1392.     }
  1393.     // Copy the stream, trim it, and write it to disk
  1394.     std::string result = stream.str ();
  1395.     boost::trim (result);
  1396.     stream.str ("");
  1397.     fs << result << "\n";
  1398.   }
  1399.   fs.close ();              // Close file
  1400.   resetLockingPermissions (file_name, file_lock);
  1401.   return (0);
  1402. }
  1403.  
  1404. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1405. int
  1406. pcl::PCDWriter::writeBinary (const std::string &file_name, const pcl::PCLPointCloud2 &cloud,
  1407.                              const Eigen::Vector4f &origin, const Eigen::Quaternionf &orientation)
  1408. {
  1409.   if (cloud.data.empty ())
  1410.   {
  1411.     PCL_ERROR ("[pcl::PCDWriter::writeBinary] Input point cloud has no data!\n");
  1412.     return (-1);
  1413.   }
  1414.   std::streamoff data_idx = 0;
  1415.   std::ostringstream oss;
  1416.   oss.imbue (std::locale::classic ());
  1417.  
  1418.   oss << generateHeaderBinary (cloud, origin, orientation) << "DATA binary\n";
  1419.   oss.flush();
  1420.   data_idx = static_cast<unsigned int> (oss.tellp ());
  1421.  
  1422. #ifdef _WIN32
  1423.   HANDLE h_native_file = CreateFile (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  1424.   if (h_native_file == INVALID_HANDLE_VALUE)
  1425.   {
  1426.     PCL_ERROR ("[pcl::PCDWriter::writeBinary] Error during CreateFile (%s)!\n", file_name.c_str());
  1427.     return (-1);
  1428.   }
  1429.   // Mandatory lock file
  1430.   boost::interprocess::file_lock file_lock;
  1431.   setLockingPermissions (file_name, file_lock);
  1432.  
  1433. #else
  1434.   int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, static_cast<mode_t> (0600));
  1435.   if (fd < 0)
  1436.   {
  1437.     PCL_ERROR ("[pcl::PCDWriter::writeBinary] Error during open (%s)!\n", file_name.c_str());
  1438.     return (-1);
  1439.   }
  1440.   // Mandatory lock file
  1441.   boost::interprocess::file_lock file_lock;
  1442.   setLockingPermissions (file_name, file_lock);
  1443.  
  1444.   // Stretch the file size to the size of the data
  1445.   off_t result = pcl_lseek (fd, getpagesize () + cloud.data.size () - 1, SEEK_SET);
  1446.   if (result < 0)
  1447.   {
  1448.     pcl_close (fd);
  1449.     resetLockingPermissions (file_name, file_lock);
  1450.     PCL_ERROR ("[pcl::PCDWriter::writeBinary] lseek errno: %d strerror: %s\n", errno, strerror (errno));
  1451.     PCL_ERROR ("[pcl::PCDWriter::writeBinary] Error during lseek ()!\n");
  1452.     return (-1);
  1453.   }
  1454.   // Write a bogus entry so that the new file size comes in effect
  1455.   result = static_cast<int> (::write (fd, "", 1));
  1456.   if (result != 1)
  1457.   {
  1458.     pcl_close (fd);
  1459.     resetLockingPermissions (file_name, file_lock);
  1460.     PCL_ERROR ("[pcl::PCDWriter::writeBinary] Error during write ()!\n");
  1461.     return (-1);
  1462.   }
  1463. #endif
  1464.   // Prepare the map
  1465. #ifdef _WIN32
  1466.   HANDLE fm = CreateFileMapping (h_native_file, NULL, PAGE_READWRITE, 0, (DWORD) (data_idx + cloud.data.size ()), NULL);
  1467.   char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, data_idx + cloud.data.size ()));
  1468.   CloseHandle (fm);
  1469.  
  1470. #else
  1471.   char *map = static_cast<char*> (mmap (0, static_cast<size_t> (data_idx + cloud.data.size ()), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
  1472.   if (map == reinterpret_cast<char*> (-1))    // MAP_FAILED
  1473.   {
  1474.     pcl_close (fd);
  1475.     resetLockingPermissions (file_name, file_lock);
  1476.     PCL_ERROR ("[pcl::PCDWriter::writeBinary] Error during mmap ()!\n");
  1477.     return (-1);
  1478.   }
  1479. #endif
  1480.  
  1481.   // copy header
  1482.   memcpy (&map[0], oss.str().c_str (), static_cast<size_t> (data_idx));
  1483.  
  1484.   // Copy the data
  1485.   memcpy (&map[0] + data_idx, &cloud.data[0], cloud.data.size ());
  1486.  
  1487. #ifndef _WIN32
  1488.   // If the user set the synchronization flag on, call msync
  1489.   if (map_synchronization_)
  1490.     msync (map, static_cast<size_t> (data_idx + cloud.data.size ()), MS_SYNC);
  1491. #endif
  1492.  
  1493.   // Unmap the pages of memory
  1494. #ifdef _WIN32
  1495.     UnmapViewOfFile (map);
  1496. #else
  1497.   if (munmap (map, static_cast<size_t> (data_idx + cloud.data.size ())) == -1)
  1498.   {
  1499.     pcl_close (fd);
  1500.     resetLockingPermissions (file_name, file_lock);
  1501.     PCL_ERROR ("[pcl::PCDWriter::writeBinary] Error during munmap ()!\n");
  1502.     return (-1);
  1503.   }
  1504. #endif
  1505.   // Close file
  1506. #ifdef _WIN32
  1507.   CloseHandle(h_native_file);
  1508. #else
  1509.   pcl_close (fd);
  1510. #endif
  1511.   resetLockingPermissions (file_name, file_lock);
  1512.   return (0);
  1513. }
  1514.  
  1515. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1516. int
  1517. pcl::PCDWriter::writeBinaryCompressed (const std::string &file_name, const pcl::PCLPointCloud2 &cloud,
  1518.                                        const Eigen::Vector4f &origin, const Eigen::Quaternionf &orientation)
  1519. {
  1520.   if (cloud.data.empty ())
  1521.   {
  1522.     PCL_ERROR ("[pcl::PCDWriter::writeBinaryCompressed] Input point cloud has no data!\n");
  1523.     return (-1);
  1524.   }
  1525.   std::streamoff data_idx = 0;
  1526.   std::ostringstream oss;
  1527.   oss.imbue (std::locale::classic ());
  1528.  
  1529.   oss << generateHeaderBinaryCompressed (cloud, origin, orientation) << "DATA binary_compressed\n";
  1530.   oss.flush ();
  1531.   data_idx = oss.tellp ();
  1532.  
  1533. #ifdef _WIN32
  1534.   HANDLE h_native_file = CreateFile (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  1535.   if (h_native_file == INVALID_HANDLE_VALUE)
  1536.   {
  1537.     PCL_ERROR ("[pcl::PCDWriter::writeBinaryCompressed] Error during CreateFile (%s)!\n", file_name.c_str ());
  1538.     return (-1);
  1539.   }
  1540. #else
  1541.   int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, static_cast<mode_t> (0600));
  1542.   if (fd < 0)
  1543.   {
  1544.     PCL_ERROR ("[pcl::PCDWriter::writeBinaryCompressed] Error during open (%s)!\n", file_name.c_str());
  1545.     return (-1);
  1546.   }
  1547. #endif
  1548.   // Mandatory lock file
  1549.   boost::interprocess::file_lock file_lock;
  1550.   setLockingPermissions (file_name, file_lock);
  1551.  
  1552.   size_t fsize = 0;
  1553.   size_t data_size = 0;
  1554.   size_t nri = 0;
  1555.   std::vector<pcl::PCLPointField> fields (cloud.fields.size ());
  1556.   std::vector<int> fields_sizes (cloud.fields.size ());
  1557.   // Compute the total size of the fields
  1558.   for (size_t i = 0; i < cloud.fields.size (); ++i)
  1559.   {
  1560.     if (cloud.fields[i].name == "_")
  1561.       continue;
  1562.    
  1563.     fields_sizes[nri] = cloud.fields[i].count * pcl::getFieldSize (cloud.fields[i].datatype);
  1564.     fsize += fields_sizes[nri];
  1565.     fields[nri] = cloud.fields[i];
  1566.     ++nri;
  1567.   }
  1568.   fields_sizes.resize (nri);
  1569.   fields.resize (nri);
  1570.  
  1571.   // Compute the size of data
  1572.   data_size = cloud.width * cloud.height * fsize;
  1573.   std::cout << "data_size="<<data_size<<" in pcd_io.cpp 1570"<<std::endl;
  1574.   //////////////////////////////////////////////////////////////////////
  1575.   // Empty array holding only the valid data
  1576.   // data_size = nr_points * point_size
  1577.   //           = nr_points * (sizeof_field_1 + sizeof_field_2 + ... sizeof_field_n)
  1578.   //           = sizeof_field_1 * nr_points + sizeof_field_2 * nr_points + ... sizeof_field_n * nr_points
  1579. //edit yamamoto
  1580. //char *only_valid_data = NULL;
  1581.     char *only_valid_data = new char [data_size];
  1582.     //char *only_valid_data = static_cast<char*> (malloc (data_size));//original
  1583.     //char *only_valid_data = static_cast<char*> (malloc (data_size));
  1584.     //assert(only_valid_data == NULL);
  1585.       std::cout<< "only_valid_data= "<<only_valid_data<<std::endl;
  1586. //only_valid_data = static_cast<char*> (malloc (data_size));
  1587.   std::cout << "only_valid_data="<<only_valid_data<<" in pcd_io.cpp 1580"<<std::endl;
  1588.   // Convert the XYZRGBXYZRGB structure to XXYYZZRGBRGB to aid compression. For
  1589.   // this, we need a vector of fields.size () (4 in this case), which points to
  1590.   // each individual plane:
  1591.   //   pters[0] = &only_valid_data[offset_of_plane_x];
  1592.   //   pters[1] = &only_valid_data[offset_of_plane_y];
  1593.   //   pters[2] = &only_valid_data[offset_of_plane_z];
  1594.   //   pters[3] = &only_valid_data[offset_of_plane_RGB];
  1595.   //
  1596.   std::vector<char*> pters (fields.size ());
  1597.   int toff = 0;
  1598.   for (size_t i = 0; i < pters.size (); ++i)
  1599.   {
  1600.     pters[i] = &only_valid_data[toff];
  1601.     toff += fields_sizes[i] * cloud.width * cloud.height;
  1602.   }
  1603.  
  1604.   // Go over all the points, and copy the data in the appropriate places
  1605.   for (size_t i = 0; i < cloud.width * cloud.height; ++i)
  1606.   {
  1607.     for (size_t j = 0; j < pters.size (); ++j)
  1608.     {
  1609.       memcpy (pters[j], &cloud.data[i * cloud.point_step + fields[j].offset], fields_sizes[j]);
  1610.       // Increment the pointer
  1611.       pters[j] += fields_sizes[j];
  1612.     }
  1613.   }
  1614.   std::cout << std::endl<<"pcd_io.cpp 1604 ok"<< std::endl;
  1615.   char* temp_buf = static_cast<char*> (malloc (static_cast<size_t> (static_cast<float> (data_size) * 1.5f + 8.0f)));
  1616.   // Compress the valid data
  1617.   std::cout<< "temp_buf= "<<temp_buf<<" 1615"<<std::endl;
  1618.   assert(temp_buf  == NULL); //check for error
  1619.   unsigned int compressed_size = pcl::lzfCompress (only_valid_data,
  1620.                                                    static_cast<unsigned int> (data_size),
  1621.                                                    &temp_buf[8],
  1622.                                                    static_cast<unsigned int> (static_cast<float> (data_size) * 1.5f));
  1623.   unsigned int compressed_final_size = 0;
  1624.   // Was the compression successful?
  1625.   if (compressed_size)
  1626.   {
  1627.     char *header = &temp_buf[0];
  1628.     memcpy (&header[0], &compressed_size, sizeof (unsigned int));
  1629.     memcpy (&header[4], &data_size, sizeof (unsigned int));
  1630.     data_size = compressed_size + 8;
  1631.     compressed_final_size = static_cast<unsigned int> (data_size + data_idx);
  1632.   }
  1633.   else
  1634.   {
  1635. #ifndef _WIN32
  1636.     pcl_close (fd);
  1637. #endif
  1638.     resetLockingPermissions (file_name, file_lock);
  1639.     throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Error during compression!");
  1640.     return (-1);
  1641.   }
  1642.  
  1643. #ifndef _WIN32
  1644.   // Stretch the file size to the size of the data
  1645.   off_t result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);
  1646.   if (result < 0)
  1647.   {
  1648.     pcl_close (fd);
  1649.     resetLockingPermissions (file_name, file_lock);
  1650.     PCL_ERROR ("[pcl::PCDWriter::writeBinaryCompressed] lseek errno: %d strerror: %s\n", errno, strerror (errno));
  1651.     PCL_ERROR ("[pcl::PCDWriter::writeBinaryCompressed] Error during lseek ()!\n");
  1652.     return (-1);
  1653.   }
  1654.   // Write a bogus entry so that the new file size comes in effect
  1655.   result = static_cast<int> (::write (fd, "", 1));
  1656.   if (result != 1)
  1657.   {
  1658.     pcl_close (fd);
  1659.     resetLockingPermissions (file_name, file_lock);
  1660.     PCL_ERROR ("[pcl::PCDWriter::writeBinaryCompressed] Error during write ()!\n");
  1661.     return (-1);
  1662.   }
  1663. #endif
  1664.  
  1665.   // Prepare the map
  1666. #ifdef _WIN32
  1667.   HANDLE fm = CreateFileMapping (h_native_file, NULL, PAGE_READWRITE, 0, compressed_final_size, NULL);
  1668.   char *map = static_cast<char*> (MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, compressed_final_size));
  1669.   CloseHandle (fm);
  1670.  
  1671. #else
  1672.   char *map = static_cast<char*> (mmap (0, compressed_final_size, PROT_WRITE, MAP_SHARED, fd, 0));
  1673.   if (map == reinterpret_cast<char*> (-1))    // MAP_FAILED
  1674.   {
  1675.     pcl_close (fd);
  1676.     resetLockingPermissions (file_name, file_lock);
  1677.     PCL_ERROR ("[pcl::PCDWriter::writeBinaryCompressed] Error during mmap ()!\n");
  1678.     return (-1);
  1679.   }
  1680. #endif
  1681.  
  1682.   // copy header
  1683.   memcpy (&map[0], oss.str ().c_str (), static_cast<size_t> (data_idx));
  1684.   // Copy the compressed data
  1685.   memcpy (&map[data_idx], temp_buf, data_size);
  1686.  
  1687. #ifndef _WIN32
  1688.   // If the user set the synchronization flag on, call msync
  1689.   if (map_synchronization_)
  1690.     msync (map, compressed_final_size, MS_SYNC);
  1691. #endif
  1692.  
  1693.   // Unmap the pages of memory
  1694. #ifdef _WIN32
  1695.     UnmapViewOfFile (map);
  1696. #else
  1697.   if (munmap (map, (compressed_final_size)) == -1)
  1698.   {
  1699.     pcl_close (fd);
  1700.     resetLockingPermissions (file_name, file_lock);
  1701.     PCL_ERROR ("[pcl::PCDWriter::writeBinaryCompressed] Error during munmap ()!\n");
  1702.     return (-1);
  1703.   }
  1704. #endif
  1705.   // Close file
  1706. #ifdef _WIN32
  1707.   CloseHandle (h_native_file);
  1708. #else
  1709.   pcl_close (fd);
  1710. #endif
  1711.   resetLockingPermissions (file_name, file_lock);
  1712.  
  1713. std::cout<<"before error"<<std::endl;
  1714. //ADD by yamamoto
  1715.   //free (only_valid_data);
  1716.  
  1717.     if(only_valid_data!=NULL)
  1718.     {
  1719.                   std::cout<< "only_valid_data= "<<only_valid_data<<std::endl;
  1720.           printf ("only_valid_data : %p\n", only_valid_data);            
  1721.           delete[]only_valid_data;
  1722.         //free(only_valid_data);
  1723.           std::cout<< "only_valid_data= "<<only_valid_data<<std::endl; 
  1724.         only_valid_data=NULL;
  1725.     }
  1726.  
  1727.   free (temp_buf);
  1728.       std::cout<< "temp_buf= "<<temp_buf<<std::endl;
  1729.       printf ("temp_buf : %p\n", temp_buf);
  1730.   temp_buf=NULL;
  1731.   return (0);
  1732. }
Advertisement
Add Comment
Please, Sign In to add comment