[Liblas-commits] hg: 3 new changesets

liblas-commits at liblas.org liblas-commits at liblas.org
Thu Mar 11 12:11:46 EST 2010


changeset 49e9583592b4 in /Volumes/Data/www/liblas.org/hg
details: http://hg.liblas.orghg?cmd=changeset;node=49e9583592b4
summary: fix #175, more detailed error messages for check_stream_state

changeset 8073c4857e8e in /Volumes/Data/www/liblas.org/hg
details: http://hg.liblas.orghg?cmd=changeset;node=8073c4857e8e
summary: fix #176 -- readvlrs reseting the file pointer and #177 -- throw an error when actual number of points in the file does not match header entry

changeset 29752c85f368 in /Volumes/Data/www/liblas.org/hg
details: http://hg.liblas.orghg?cmd=changeset;node=29752c85f368
summary: typo

diffstat:

 apps/las2las.c                    |   2 +-
 include/liblas/detail/utility.hpp |  18 +++++-----
 src/detail/reader/header.cpp      |  60 +++++++++++++++++++++++++++++++++-----
 3 files changed, 61 insertions(+), 19 deletions(-)

diffs (188 lines):

diff -r c34ee6db25b2 -r 29752c85f368 apps/las2las.c
--- a/apps/las2las.c	Fri Mar 05 14:02:50 2010 -0600
+++ b/apps/las2las.c	Thu Mar 11 11:06:18 2010 -0600
@@ -1090,7 +1090,7 @@
         ret = LASWriter_WritePoint(writer,p);
         
         if (ret == LE_Warning) {
-            LASError_Print("Unable to write invalid point.  Use --skip_invalid to avoid this problem (you will loose data in the translation)");
+            LASError_Print("Unable to write invalid point.  Use --skip_invalid to avoid this problem (you will lose data in the translation)");
             exit(1);
         }
         p  = LASReader_GetNextPoint(reader);
diff -r c34ee6db25b2 -r 29752c85f368 include/liblas/detail/utility.hpp
--- a/include/liblas/detail/utility.hpp	Fri Mar 05 14:02:50 2010 -0600
+++ b/include/liblas/detail/utility.hpp	Thu Mar 11 11:06:18 2010 -0600
@@ -351,7 +351,7 @@
     //       builds to increase performance.
 #if defined(DEBUG) || defined(_DEBUG)
     // Test stream state bits
-    if (srtm.eof())
+    if (srtm.eof()) 
         throw std::out_of_range("end of file encountered");
     else if (srtm.fail())
         throw std::runtime_error("non-fatal I/O error occured");
@@ -372,7 +372,7 @@
 {
     // TODO: Review and redesign errors handling logic if necessary
     if (!src)
-        throw std::runtime_error("detail::liblas::read_n input stream is not readable");
+        throw std::runtime_error("detail::liblas::read_n<T> input stream is not readable");
 
     src.read(detail::as_buffer(dest), num);
 
@@ -387,7 +387,7 @@
 {
     // TODO: Review and redesign errors handling logic if necessary
     if (!src)
-        throw std::runtime_error("detail::liblas::read_n input stream is not readable");
+        throw std::runtime_error("detail::liblas::read_n<PointRecord> input stream is not readable");
 
     src.read(detail::as_buffer(dest), num);
     check_stream_state(src);
@@ -409,7 +409,7 @@
 {
     // TODO: Review and redesign errors handling logic if necessary
     if (!src)
-        throw std::runtime_error("detail::liblas::read_n input stream is not readable");
+        throw std::runtime_error("detail::liblas::read_n<VLRHeader> input stream is not readable");
 
     src.read(detail::as_buffer(dest), num);
     check_stream_state(src);
@@ -427,7 +427,7 @@
 
     // TODO: Review and redesign errors handling logic if necessary
     if (!src)
-        throw std::runtime_error("detail::liblas::read_n input stream is not readable");
+        throw std::runtime_error("detail::liblas::read_n<std::string> input stream is not readable");
 
     // Read bytes into temporary buffer then assign as string
     std::size_t const bufsize = static_cast<std::size_t>(num);
@@ -444,7 +444,7 @@
 inline void write_n(std::ostream& dest, T const& src, std::streamsize const& num)
 {
     if (!dest)
-        throw std::runtime_error("detail::liblas::write_n: output stream is not writable");
+        throw std::runtime_error("detail::liblas::write_n<T>: output stream is not writable");
 
     // Fix little-endian
     T& tmp = const_cast<T&>(src);
@@ -458,7 +458,7 @@
 inline void write_n<PointRecord>(std::ostream& dest, PointRecord const& src, std::streamsize const& num)
 {
     if (!dest)
-        throw std::runtime_error("detail::liblas::write_n: output stream is not writable");
+        throw std::runtime_error("detail::liblas::write_n<PointRecord>: output stream is not writable");
 
     // Fix little-endian
     PointRecord& tmp = const_cast<PointRecord&>(src);
@@ -480,7 +480,7 @@
 inline void write_n<VLRHeader>(std::ostream& dest, VLRHeader const& src, std::streamsize const& num)
 {
     if (!dest)
-        throw std::runtime_error("detail::liblas::write_n: output stream is not writable");
+        throw std::runtime_error("detail::liblas::write_n<VLRHeader>: output stream is not writable");
 
     // Fix little-endian
     VLRHeader& tmp = const_cast<VLRHeader&>(src);
@@ -496,7 +496,7 @@
 inline void write_n<std::string>(std::ostream& dest, std::string const& src, std::streamsize const& num)
 {
     if (!dest)
-        throw std::runtime_error("detail::liblas::write_n: output stream is not writable");
+        throw std::runtime_error("detail::liblas::write_n<std::string>: output stream is not writable");
 
     dest.write(src.c_str(), num);
     check_stream_state(dest);
diff -r c34ee6db25b2 -r 29752c85f368 src/detail/reader/header.cpp
--- a/src/detail/reader/header.cpp	Fri Mar 05 14:02:50 2010 -0600
+++ b/src/detail/reader/header.cpp	Thu Mar 11 11:06:18 2010 -0600
@@ -211,18 +211,59 @@
 
     // We're going to check the two bytes off the end of the header to 
     // see if they're pad bytes anyway.  Some softwares, notably older QTModeler, 
-    // write 1.0-style pad bytes off the end of their files but state that the
+    // write 1.0-style pad bytes off the end of their header but state that the
     // offset is actually 2 bytes back.  We need to set the dataoffset 
     // appropriately in those cases anyway. 
     m_ifs.seekg(m_header.GetDataOffset());
-    bool has_pad = HasLAS10PadSignature();
-    if (has_pad) {
+
+    if (HasLAS10PadSignature()) {
         std::streamsize const current_pos = m_ifs.tellg();
         m_ifs.seekg(current_pos + 2);
         m_header.SetDataOffset(m_header.GetDataOffset() + 2);
     }
+     
+    // only go read VLRs if we have them.
+    if (m_header.GetRecordsCount() > 0)
+        readvlrs();
+
+    // Check that the point count actually describes the number of points 
+    // in the file.  If it doesn't, we're going to throw an error telling 
+    // the user why.  It may also be a problem that the dataoffset is 
+    // really what is wrong, but there's no real way to know that unless 
+    // you go start mucking around in the bytes with hexdump or od
+
+    // Seek to the beginning
+    m_ifs.seekg(0, std::ios::beg);
+    std::ios::pos_type beginning = m_ifs.tellg();
+
+    // Seek to the end
+    m_ifs.seekg(0, std::ios::end);
+    std::ios::pos_type end = m_ifs.tellg();
+    std::ios::off_type size = end - beginning;
     
-    readvlrs();
+    // Figure out how many points we have 
+    std::ios::off_type count = (end - static_cast<std::ios::off_type>(m_header.GetDataOffset())) / 
+                                 static_cast<std::ios::off_type>(m_header.GetDataRecordLength());
+    
+    if ( m_header.GetPointRecordsCount() != static_cast<uint32_t>(count)) {
+        std::ostringstream msg; 
+        msg <<  "The number of points in the header that was set "
+                "by the software '" << m_header.GetSoftwareId() <<
+                "' does not match the actual number of points in the file "
+                "as determined by subtracting the data offset (" 
+                <<m_header.GetDataOffset() << ") from the file length (" 
+                << size <<  ") and dividing by the point record length(" 
+                << m_header.GetDataRecordLength() << "). "
+                " Actual number of points: " << count << 
+                " Header-specified number of points: " 
+                << m_header.GetPointRecordsCount() ;
+        throw std::runtime_error(msg.str());
+        
+    }
+    
+    // Seek to the data offset so we can start reading points
+    m_ifs.seekg(m_header.GetDataOffset());
+
 }
 
 bool Header::HasLAS10PadSignature() 
@@ -234,7 +275,8 @@
 
     std::streamsize const current_pos = m_ifs.tellg();
     
-    // If our little test reads off the end, we'll try to put the 
+    // If our little test reads off the end of the file (in the case 
+    // of a file with just a header and no points), we'll try to put the 
     // borken dishes back up in the cabinet
     try
     {
@@ -258,10 +300,10 @@
     
     // Put the stream back where we found it
     m_ifs.seekg(current_pos, std::ios::beg);
-
-    // FIXME: we have to worry about swapping issues
-    // but some people write the pad bytes backwards 
-    // anyway.  Let's check both ways.
+    
+    // Let's check both ways in case people were 
+    // careless with their swapping.  This will do no good 
+    // when we go to read point data though.
     bool found = false;
     if (sgn1 == pad2 && sgn2 == pad1) found = true;
     if (sgn1 == pad1 && sgn2 == pad2) found = true;


More information about the Liblas-commits mailing list