[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