Пример #1
0
Common::SeekableReadStream *GFF4Struct::getData(uint32 field) const {
	const Field *f;
	Common::SeekableReadStream *data = getField(field, f);
	if (!data)
		return 0;

	const uint32 count = getListCount(*data, *f);
	const uint32 size  = getFieldSize(f->type);

	if ((size == 0) || (count == 0))
		return 0;

	const uint32 dataBegin = data->pos();
	const uint32 dataEnd   = data->pos() + (count * size);

	return new Common::SeekableSubReadStream(data, dataBegin, dataEnd);
}
Пример #2
0
template <typename PointInT, typename PointOutT> void
pcl::copyPointCloud (const pcl::PointCloud<PointInT> &cloud_in,
                     const std::vector<pcl::PointIndices> &indices,
                     pcl::PointCloud<PointOutT> &cloud_out)
{
    int nr_p = 0;
    for (size_t i = 0; i < indices.size (); ++i)
        nr_p += indices[i].indices.size ();

    // Do we want to copy everything? Remember we assume UNIQUE indices
    if (nr_p == cloud_in.points.size ())
    {
        copyPointCloud<PointInT, PointOutT> (cloud_in, cloud_out);
        return;
    }

    // Allocate enough space and copy the basics
    cloud_out.points.resize (nr_p);
    cloud_out.header   = cloud_in.header;
    cloud_out.width    = nr_p;
    cloud_out.height   = 1;
    cloud_out.is_dense = cloud_in.is_dense;
    cloud_out.sensor_orientation_ = cloud_in.sensor_orientation_;
    cloud_out.sensor_origin_ = cloud_in.sensor_origin_;

    // Copy all the data fields from the input cloud to the output one
    typedef typename pcl::traits::fieldList<PointInT>::type FieldListInT;
    typedef typename pcl::traits::fieldList<PointOutT>::type FieldListOutT;
    typedef typename pcl::intersect<FieldListInT, FieldListOutT>::type FieldList;

    // If the point types are the same, don't copy one by one
    if (isSamePointType<PointInT, PointOutT> ())
    {
        // Iterate over each cluster
        int cp = 0;
        for (size_t cc = 0; cc < indices.size (); ++cc)
        {
            // Iterate over each idx
            for (size_t i = 0; i < indices[cc].indices.size (); ++i)
            {
                cloud_out.points[cp] = cloud_in.points[indices[cc].indices[i]];
                ++cp;
            }
        }
        return;
    }

    std::vector<pcl::PCLPointField> fields_in, fields_out;
    pcl::for_each_type<FieldListInT> (pcl::detail::FieldAdder<PointInT> (fields_in));
    pcl::for_each_type<FieldListOutT> (pcl::detail::FieldAdder<PointOutT> (fields_out));

    // RGB vs RGBA is an official missmatch until PCL 2.0, so we need to search for it and
    // fix it manually
    int rgb_idx_in = -1, rgb_idx_out = -1;
    for (size_t i = 0; i < fields_in.size (); ++i)
        if (fields_in[i].name == "rgb" || fields_in[i].name == "rgba")
        {
            rgb_idx_in = int (i);
            break;
        }
    for (size_t i = 0; i < fields_out.size (); ++i)
        if (fields_out[i].name == "rgb" || fields_out[i].name == "rgba")
        {
            rgb_idx_out = int (i);
            break;
        }

    // We have one of the two cases: RGB vs RGBA or RGBA vs RGB
    if (rgb_idx_in != -1 && rgb_idx_out != -1 &&
            fields_in[rgb_idx_in].name != fields_out[rgb_idx_out].name)
    {
        size_t field_size_in  = getFieldSize (fields_in[rgb_idx_in].datatype),
               field_size_out = getFieldSize (fields_out[rgb_idx_out].datatype);

        if (field_size_in == field_size_out)
        {
            // Iterate over each cluster
            int cp = 0;
            for (size_t cc = 0; cc < indices.size (); ++cc)
            {
                // Iterate over each idx
                for (size_t i = 0; i < indices[cc].indices.size (); ++i)
                {
                    // Iterate over each dimension
                    pcl::for_each_type <FieldList> (pcl::NdConcatenateFunctor <PointInT, PointOutT> (cloud_in.points[indices[cc].indices[i]], cloud_out.points[cp]));
                    // Copy RGB<->RGBA
                    memcpy (reinterpret_cast<char*> (&cloud_out.points[cp]) + fields_out[rgb_idx_out].offset, reinterpret_cast<const char*> (&cloud_in.points[indices[cp].indices[i]]) + fields_in[rgb_idx_in].offset, field_size_in);
                    ++cp;
                }
            }
            return;
        }
    }

    // Iterate over each cluster
    int cp = 0;
    for (size_t cc = 0; cc < indices.size (); ++cc)
    {
        // Iterate over each idx
        for (size_t i = 0; i < indices[cc].indices.size (); ++i)
        {
            // Iterate over each dimension
            pcl::for_each_type <FieldList> (pcl::NdConcatenateFunctor <PointInT, PointOutT> (cloud_in.points[indices[cc].indices[i]], cloud_out.points[cp]));
            ++cp;
        }
    }
}
Пример #3
0
template <typename PointInT, typename PointOutT> void
pcl::copyPointCloud (const pcl::PointCloud<PointInT> &cloud_in,
                     const std::vector<int, Eigen::aligned_allocator<int> > &indices,
                     pcl::PointCloud<PointOutT> &cloud_out)
{
    // Allocate enough space and copy the basics
    cloud_out.points.resize (indices.size ());
    cloud_out.header   = cloud_in.header;
    cloud_out.width    = static_cast<uint32_t> (indices.size ());
    cloud_out.height   = 1;
    cloud_out.is_dense = cloud_in.is_dense;
    cloud_out.sensor_orientation_ = cloud_in.sensor_orientation_;
    cloud_out.sensor_origin_ = cloud_in.sensor_origin_;

    // Copy all the data fields from the input cloud to the output one
    typedef typename pcl::traits::fieldList<PointInT>::type FieldListInT;
    typedef typename pcl::traits::fieldList<PointOutT>::type FieldListOutT;
    typedef typename pcl::intersect<FieldListInT, FieldListOutT>::type FieldList;

    // If the point types are the same, don't copy one by one
    if (isSamePointType<PointInT, PointOutT> ())
    {
        // Iterate over each point
        for (size_t i = 0; i < indices.size (); ++i)
            memcpy (&cloud_out.points[i], &cloud_in.points[indices[i]], sizeof (PointInT));
        return;
    }

    std::vector<pcl::PCLPointField> fields_in, fields_out;
    pcl::for_each_type<FieldListInT> (pcl::detail::FieldAdder<PointInT> (fields_in));
    pcl::for_each_type<FieldListOutT> (pcl::detail::FieldAdder<PointOutT> (fields_out));

    // RGB vs RGBA is an official missmatch until PCL 2.0, so we need to search for it and
    // fix it manually
    int rgb_idx_in = -1, rgb_idx_out = -1;
    for (size_t i = 0; i < fields_in.size (); ++i)
        if (fields_in[i].name == "rgb" || fields_in[i].name == "rgba")
        {
            rgb_idx_in = int (i);
            break;
        }
    for (size_t i = 0; i < fields_out.size (); ++i)
        if (fields_out[i].name == "rgb" || fields_out[i].name == "rgba")
        {
            rgb_idx_out = int (i);
            break;
        }

    // We have one of the two cases: RGB vs RGBA or RGBA vs RGB
    if (rgb_idx_in != -1 && rgb_idx_out != -1 &&
            fields_in[rgb_idx_in].name != fields_out[rgb_idx_out].name)
    {
        size_t field_size_in  = getFieldSize (fields_in[rgb_idx_in].datatype),
               field_size_out = getFieldSize (fields_out[rgb_idx_out].datatype);

        if (field_size_in == field_size_out)
        {
            for (size_t i = 0; i < indices.size (); ++i)
            {
                // Copy the rest
                pcl::for_each_type<FieldList> (pcl::NdConcatenateFunctor <PointInT, PointOutT> (cloud_in.points[indices[i]], cloud_out.points[i]));
                // Copy RGB<->RGBA
                memcpy (reinterpret_cast<char*> (&cloud_out.points[i]) + fields_out[rgb_idx_out].offset, reinterpret_cast<const char*> (&cloud_in.points[indices[i]]) + fields_in[rgb_idx_in].offset, field_size_in);
            }
            return;
        }
    }

    // Iterate over each point if no RGB/RGBA or if their size is different
    for (size_t i = 0; i < indices.size (); ++i)
        // Iterate over each dimension
        pcl::for_each_type <FieldList> (pcl::NdConcatenateFunctor <PointInT, PointOutT> (cloud_in.points[indices[i]], cloud_out.points[i]));
}
Пример #4
0
template <typename PointT> int
pcl::PCDWriter::writeBinary (const std::string &file_name, 
                             const pcl::PointCloud<PointT> &cloud, 
                             const std::vector<int> &indices)
{
  if (cloud.points.empty () || indices.empty ())
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Input point cloud has no data or empty indices given!");
    return (-1);
  }
  int data_idx = 0;
  std::ostringstream oss;
  oss << generateHeader<PointT> (cloud, static_cast<int> (indices.size ())) << "DATA binary\n";
  oss.flush ();
  data_idx = static_cast<int> (oss.tellp ());

#if _WIN32
  HANDLE h_native_file = CreateFileA (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if(h_native_file == INVALID_HANDLE_VALUE)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during CreateFile!");
    return (-1);
  }
#else
  int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, static_cast<mode_t> (0600));
  if (fd < 0)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during open!");
    return (-1);
  }
#endif

  std::vector<sensor_msgs::PointField> fields;
  std::vector<int> fields_sizes;
  size_t fsize = 0;
  size_t data_size = 0;
  size_t nri = 0;
  pcl::getFields (cloud, fields);
  // Compute the total size of the fields
  for (size_t i = 0; i < fields.size (); ++i)
  {
    if (fields[i].name == "_")
      continue;
    
    int fs = fields[i].count * getFieldSize (fields[i].datatype);
    fsize += fs;
    fields_sizes.push_back (fs);
    fields[nri++] = fields[i];
  }
  fields.resize (nri);
  
  data_size = indices.size () * fsize;

  // Prepare the map
#if _WIN32
  HANDLE fm = CreateFileMapping (h_native_file, NULL, PAGE_READWRITE, 0, data_idx + data_size, NULL);
  char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, data_idx + data_size));
  CloseHandle (fm);

#else
  // Stretch the file size to the size of the data
  int result = static_cast<int> (pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET));
  if (result < 0)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during lseek ()!");
    return (-1);
  }
  // Write a bogus entry so that the new file size comes in effect
  result = static_cast<int> (::write (fd, "", 1));
  if (result != 1)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during write ()!");
    return (-1);
  }

  char *map = static_cast<char*> (mmap (0, data_idx + data_size, PROT_WRITE, MAP_SHARED, fd, 0));
  if (map == reinterpret_cast<char*> (-1)) //MAP_FAILED)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during mmap ()!");
    return (-1);
  }
#endif

  // Copy the header
  memcpy (&map[0], oss.str ().c_str (), data_idx);

  char *out = &map[0] + data_idx;
  // Copy the data
  for (size_t i = 0; i < indices.size (); ++i)
  {
    int nrj = 0;
    for (size_t j = 0; j < fields.size (); ++j)
    {
      memcpy (out, reinterpret_cast<const char*> (&cloud.points[indices[i]]) + fields[j].offset, fields_sizes[nrj]);
      out += fields_sizes[nrj++];
    }
  }

#if !_WIN32
  // If the user set the synchronization flag on, call msync
  if (map_synchronization_)
    msync (map, data_idx + data_size, MS_SYNC);
#endif

  // Unmap the pages of memory
#if _WIN32
    UnmapViewOfFile (map);
#else
  if (munmap (map, (data_idx + data_size)) == -1)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during munmap ()!");
    return (-1);
  }
#endif
  // Close file
#if _WIN32
  CloseHandle(h_native_file);
#else
  pcl_close (fd);
#endif
  return (0);
}
Пример #5
0
javacall_result
javacall_security_keystore_get_next(javacall_handle keyStoreHandle,
                                    unsigned short** /*OUT*/ owner,
                                    int*             /*OUT*/ ownerSize,
                                    javacall_int64*  /*OUT*/ validityStartMillissec,
                                    javacall_int64*  /*OUT*/ validityEndMillisec,
                                    unsigned char**  /*OUT*/ modulus,
                                    int*             /*OUT*/ modulusSize,
                                    unsigned char**  /*OUT*/ exponent,
                                    int*             /*OUT*/ exponentSize,
                                    char**           /*OUT*/ domain,
                                    int*             /*OUT*/ domainSize) {

    int tmp_size;
    javacall_result res = JAVACALL_OK;

    javacall_reset_local_variables();

    /* getFieldSize moves currentPosition forward */
    *ownerSize = getFieldSize();
    tmp_size = (*ownerSize)+2;

    *owner = (unsigned short*) malloc(tmp_size);
    if(*owner == NULL) {
        printf("Can not allocate memory for owner.\n");
        return JAVACALL_FAIL;
    }

    local_owner = *owner;

    memset(*owner, 0, tmp_size);
    memcpy(*owner, currentPosition, *ownerSize);

    /* move currentPosition forward */
    currentPosition+=*ownerSize;

    /* get validity Start time */
    /* verify_mainks_fields() moves currentPosition forward */
    res = verify_mainks_fields(NOT_BEFORE_TAG, LONG_TYPE);
    if(res != JAVACALL_OK) {
        return res;
    }

    /* javacall_read_int64_value moves currentPosition forward */
    *validityStartMillissec = javacall_read_int64_value();


    /* get validity end time */
    /* verify_mainks_fields() moves currentPosition forward */
    res = verify_mainks_fields(NOT_AFTER_TAG, LONG_TYPE);
    if(res != JAVACALL_OK) {
        return res;
    }

    /* javacall_read_int64_value moves currentPosition forward */
    *validityEndMillisec = javacall_read_int64_value();


    /* verify_mainks_fields() moves currentPosition forward */
    res = verify_mainks_fields(MODULUS_TAG, BINARY_TYPE);
    if(res != JAVACALL_OK) {
        return res;
    }

    /* getFieldSize moves currentPosition forward */
    *modulusSize = getFieldSize();

    tmp_size = (*modulusSize)+2;
    *modulus = (unsigned char*)malloc(tmp_size);
    if(*modulus == NULL) {
        printf("Can not allocate memory for modulus data\n");
        return JAVACALL_FAIL;
    }

    local_modulus = *modulus;

    memset(*modulus, 0, tmp_size);
    memcpy(*modulus,currentPosition,*modulusSize);
    currentPosition+=*modulusSize;

    /* verify_mainks_fields() moves currentPosition forward */
    res = verify_mainks_fields(EXPONENT_TAG, BINARY_TYPE);
    if(res != JAVACALL_OK) {
        return res;
    }

    /* getFieldSize moves currentPosition forward */
    *exponentSize = getFieldSize();

    tmp_size = (*exponentSize)+2;
    *exponent = (unsigned char*)malloc(tmp_size);
    if(*exponent == NULL) {
        printf("Can not allocate memory for exponent data\n");
        return JAVACALL_FAIL;
    }

    local_exponent = *exponent;

    memset(*exponent, 0, tmp_size);
    memcpy(*exponent,currentPosition,*exponentSize);
    currentPosition+=*exponentSize;


    /* verify_mainks_fields() moves currentPosition forward */
    res = verify_mainks_fields(DOMAIN_TAG, STRING_TYPE);
    if(res != JAVACALL_OK) {
        return res;
    }

    /* getFieldSize moves currentPosition forward */
    *domainSize = getFieldSize();

    tmp_size = (*domainSize)+2;
    *domain = malloc(tmp_size);
    if(*domain == NULL) {
        printf("Can not allocate memory for domain data\n");
        return JAVACALL_FAIL;
    }

    local_domain = *domain;

    memset(*domain, 0, tmp_size);
    memcpy(*domain, currentPosition, *domainSize);
    currentPosition+=*domainSize;

    return JAVACALL_OK;
} /* end of javacall_security_keystore_get_next */
Пример #6
0
/**
 * @brief Get exif directory structure contained in file (if any)
 *          This is internal function and is not exposed to client
 *
 *  @return Map where key is tag number and value is ExifEntry_t structure
 */
std::map<int, ExifEntry_t > ExifReader::getExif()
{
    const std::streamsize markerSize = 2;
    const std::streamsize offsetToTiffHeader = 6; //bytes from Exif size field to the first TIFF header
    unsigned char appMarker[markerSize];
    m_exif.erase( m_exif.begin(), m_exif.end() );

    std::streamsize count;

    bool exifFound = false, stopSearch = false;
    while( ( !m_stream.eof() ) && !exifFound && !stopSearch )
    {
        m_stream.read( reinterpret_cast<char*>(appMarker), markerSize );
        count = m_stream.gcount();
        if( count < markerSize )
        {
            break;
        }
        unsigned char marker = appMarker[1];
        size_t bytesToSkip;
        size_t exifSize;
        switch( marker )
        {
            //For all the markers just skip bytes in file pointed by followed two bytes (field size)
            case SOF0: case SOF2: case DHT: case DQT: case DRI: case SOS:
            case RST0: case RST1: case RST2: case RST3: case RST4: case RST5: case RST6: case RST7:
            case APP0: case APP2: case APP3: case APP4: case APP5: case APP6: case APP7: case APP8:
            case APP9: case APP10: case APP11: case APP12: case APP13: case APP14: case APP15:
            case COM:
                bytesToSkip = getFieldSize();
                if (bytesToSkip < markerSize) {
                    throw ExifParsingError();
                }
                m_stream.seekg( static_cast<long>( bytesToSkip - markerSize ), m_stream.cur );
                if ( m_stream.fail() ) {
                    throw ExifParsingError();
                }
                break;

            //SOI and EOI don't have the size field after the marker
            case SOI: case EOI:
                break;

            case APP1: //actual Exif Marker
                exifSize = getFieldSize();
                if (exifSize <= offsetToTiffHeader) {
                    throw ExifParsingError();
                }
                m_data.resize( exifSize - offsetToTiffHeader );
                m_stream.seekg( static_cast<long>( offsetToTiffHeader ), m_stream.cur );
                if ( m_stream.fail() ) {
                    throw ExifParsingError();
                }
                m_stream.read( reinterpret_cast<char*>(&m_data[0]), exifSize - offsetToTiffHeader );
                count = m_stream.gcount();
                exifFound = true;
                break;

            default: //No other markers are expected according to standard. May be a signal of error
                stopSearch = true;
                break;
        }
    }

    if( !exifFound )
    {
        return m_exif;
    }

    parseExif();

    return m_exif;
}
Пример #7
0
/**
 * @brief Get exif directory structure contained in jpeg file (if any)
 *          This is internal function and is not exposed to client
 *
 *  @return Map where key is tag number and value is ExifEntry_t structure
 */
std::map<int, ExifEntry_t > ExifReader::getExif()
{
    const size_t markerSize = 2;
    const size_t offsetToTiffHeader = 6; //bytes from Exif size field to the first TIFF header
    unsigned char appMarker[markerSize];
    m_exif.erase( m_exif.begin(), m_exif.end() );

    size_t count;

    FILE* f = fopen( m_filename.c_str(), "rb" );

    if( !f )
    {
        return m_exif; //Until this moment the map is empty
    }

    bool exifFound = false;
    while( ( !feof( f ) ) && !exifFound )
    {
        count = fread( appMarker, sizeof(unsigned char), markerSize, f );
        if( count < markerSize )
        {
            break;
        }
        unsigned char marker = appMarker[1];
        size_t bytesToSkip;
        size_t exifSize;
        switch( marker )
        {
            //For all the markers just skip bytes in file pointed by followed two bytes (field size)
            case SOF0: case SOF2: case DHT: case DQT: case DRI: case SOS:
            case RST0: case RST1: case RST2: case RST3: case RST4: case RST5: case RST6: case RST7:
            case APP0: case APP2: case APP3: case APP4: case APP5: case APP6: case APP7: case APP8:
            case APP9: case APP10: case APP11: case APP12: case APP13: case APP14: case APP15:
            case COM:
                bytesToSkip = getFieldSize( f );
                fseek( f, static_cast<long>( bytesToSkip - markerSize ), SEEK_CUR );
                break;

            //SOI and EOI don't have the size field after the marker
            case SOI: case EOI:
                break;

            case APP1: //actual Exif Marker
                exifSize = getFieldSize(f);
                m_data.resize( exifSize - offsetToTiffHeader );
                fseek(f, static_cast<long>( offsetToTiffHeader ), SEEK_CUR);
                count = fread( &m_data[0], sizeof( unsigned char ), exifSize - offsetToTiffHeader, f );
                exifFound = true;
                break;

            default: //No other markers are expected according to standard. May be a signal of error
                break;
        }
    }

    fclose(f);

    if( !exifFound )
    {
        return m_exif;
    }

    parseExif();

    return m_exif;
}
Пример #8
0
template<typename PointT> int
pcl::PCDWriter::appendBinary(const std::string &file_name, 
                             const pcl::PointCloud<PointT> &cloud)
{
  if(cloud.empty())
  {
    throw pcl::IOException("[pcl::PCDWriter::appendBinary] Input point cloud has no data!");
    return -1;
  }

  if(!boost::filesystem::exists(file_name))
    return writeBinary(file_name, cloud);

  std::ifstream file_istream;
  file_istream.open(file_name.c_str(), std::ifstream::binary);
  if(!file_istream.good())
  {
    throw pcl::IOException("[pcl::PCDWriter::appendBinary] Error opening file for reading");
    return -1;
  }
  file_istream.seekg(0, std::ios_base::end);
  size_t file_size = file_istream.tellg();
  file_istream.close();

  pcl::PCLPointCloud2 tmp_cloud;
  PCDReader reader;
  if(reader.readHeader(file_name, tmp_cloud) != 0)
  {
    throw pcl::IOException("[pcl::PCDWriter::appendBinary] Failed reading header");
    return -1;
  }
  if(tmp_cloud.height != 1 || cloud.height != 1)
  {
    throw pcl::IOException("[pcl::PCDWriter::appendBinary] can't use appendBinary with a point cloud that "
      "has height different than 1!");
    return -1;
  }
  tmp_cloud.width += cloud.width;
  std::ostringstream oss;
  pcl::PointCloud<PointT> tmp_cloud2;
  // copy the header values:
  tmp_cloud2.header = tmp_cloud.header;
  tmp_cloud2.width = tmp_cloud.width;
  tmp_cloud2.height = tmp_cloud.height;
  tmp_cloud2.is_dense = tmp_cloud.is_dense;
  
  oss << PCDWriter::generateHeader(tmp_cloud2, tmp_cloud2.width) << "DATA binary\n";
  size_t data_idx = oss.tellp();
  
#if _WIN32
  HANDLE h_native_file = CreateFileA (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (h_native_file == INVALID_HANDLE_VALUE)
  {
    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during CreateFile!");
    return (-1);
  }
#else
  int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_APPEND, static_cast<mode_t> (0600));
  if (fd < 0)
  {
    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during open!");
    return (-1);
  }
#endif
  // Mandatory lock file
  boost::interprocess::file_lock file_lock;
  setLockingPermissions (file_name, file_lock);

  std::vector<pcl::PCLPointField> fields;
  std::vector<int> fields_sizes;
  size_t fsize = 0;
  size_t data_size = 0;
  size_t nri = 0;
  pcl::getFields (cloud, fields);
  // Compute the total size of the fields
  for (size_t i = 0; i < fields.size (); ++i)
  {
    if (fields[i].name == "_")
      continue;

    int fs = fields[i].count * getFieldSize (fields[i].datatype);
    fsize += fs;
    fields_sizes.push_back (fs);
    fields[nri++] = fields[i];
  }
  fields.resize (nri);

  data_size = cloud.points.size () * fsize;

  data_idx += (tmp_cloud.width - cloud.width) * fsize;
  if (data_idx != file_size)
  {
    const char *msg = "[pcl::PCDWriter::appendBinary] The expected data size and the current data size are different!";
    PCL_WARN(msg);
    throw pcl::IOException (msg);
    return -1;
  }

  // Prepare the map
#if _WIN32
  HANDLE fm = CreateFileMappingA (h_native_file, NULL, PAGE_READWRITE, 0, (DWORD) (data_idx + data_size), NULL);
  char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, data_idx + data_size));
  CloseHandle (fm);
#else
  // Stretch the file size to the size of the data
  off_t result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);

  if (result < 0)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    PCL_ERROR ("[pcl::PCDWriter::appendBinary] lseek errno: %d strerror: %s\n", errno, strerror (errno));

    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during lseek ()!");
    return (-1);
  }
  // Write a bogus entry so that the new file size comes in effect
  result = static_cast<int> (::write (fd, "", 1));
  if (result != 1)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during write ()!");
    return (-1);
  }

  char *map = static_cast<char*> (mmap (0, data_idx + data_size, PROT_WRITE, MAP_SHARED, fd, 0));
  if (map == reinterpret_cast<char*> (-1)) //MAP_FAILED)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during mmap ()!");
    return (-1);
  }
#endif

  char* out = &map[0] + data_idx;
  // Copy the data
  for (size_t i = 0; i < cloud.points.size (); ++i)
  {
    int nrj = 0;
    for (size_t j = 0; j < fields.size (); ++j)
    {
      memcpy (out, reinterpret_cast<const char*> (&cloud.points[i]) + fields[j].offset, fields_sizes[nrj]);
      out += fields_sizes[nrj++];
    }
  }

  // write the new header:
  std::string header(oss.str());
  memcpy(map, header.c_str(), header.size());


  // If the user set the synchronization flag on, call msync
#if !_WIN32
  if (map_synchronization_)
    msync (map, data_idx + data_size, MS_SYNC);
#endif

  // Unmap the pages of memory
#if _WIN32
  UnmapViewOfFile (map);
#else
  if (munmap (map, (data_idx + data_size)) == -1)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during munmap ()!");
    return (-1);
  }
#endif
  // Close file
#if _WIN32
  CloseHandle (h_native_file);
#else
  pcl_close (fd);
#endif

  resetLockingPermissions (file_name, file_lock);
  return 0;
}