diff --git a/CMakeLists.txt b/CMakeLists.txt index bf9bef5c4a..fa52cd303c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,7 +141,7 @@ else() # Recommended C++ compilation flags # -Weffc++ set(PDAL_COMMON_CXX_FLAGS - "-pedantic -Wall -Wpointer-arith -Wcast-align -Wcast-qual -Wfloat-equal -Wredundant-decls -Wno-long-long") + "-pedantic -Wall -Wpointer-arith -Wcast-align -Wcast-qual -Wfloat-equal -Wredundant-decls -Wno-long-long -fPIC") if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) diff --git a/include/pdal/PointBuffer.hpp b/include/pdal/PointBuffer.hpp index 50845858e7..94d80175b2 100644 --- a/include/pdal/PointBuffer.hpp +++ b/include/pdal/PointBuffer.hpp @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -95,6 +96,7 @@ class PDAL_DLL PointBuffer template T getRawField(std::size_t pointIndex, std::size_t pointBytePosition) const; template void setField(Dimension const& dim, std::size_t pointIndex, T value); + template static Target saturation_cast(Source const& src); // bulk copy all the fields from the given point into this object // NOTE: this is only legal if the src and dest schemas are exactly the same // (later, this will be implemented properly, to handle the general cases slowly and the best case quickly) @@ -181,7 +183,20 @@ class PDAL_DLL PointBuffer schema::size_type m_byteSize; }; +template +inline Target PointBuffer::saturation_cast(Source const& src) { + try { + return boost::numeric_cast(src); + } + catch (boost::numeric::negative_overflow const&) { + return std::numeric_limits::min(); + } + catch (boost::numeric::positive_overflow const&) { + return std::numeric_limits::max(); + } + +} template inline void PointBuffer::setField(pdal::Dimension const& dim, std::size_t pointIndex, T value) @@ -261,31 +276,31 @@ inline T PointBuffer::getField(pdal::Dimension const& dim, std::size_t pointInde { case dimension::SignedByte: i8 = *(boost::int8_t*)(void*)p; - output = boost::lexical_cast(i8); + output = saturation_cast(i8); break; case dimension::UnsignedByte: u8 = *(boost::uint8_t*)(void*)p; - output = boost::lexical_cast(u8); + output = saturation_cast(u8); break; case dimension::SignedInteger: if (dim.getByteSize() == 1 ) { i8 = *(boost::int8_t*)(void*)p; - output = boost::lexical_cast(i8); + output = saturation_cast(i8); } else if (dim.getByteSize() == 2) { i16 = *(boost::int16_t*)(void*)p; - output = boost::lexical_cast(i16); + output = saturation_cast(i16); } else if (dim.getByteSize() == 4) { i32 = *(boost::int32_t*)(void*)p; - output = boost::lexical_cast(i32); + output = saturation_cast(i32); } else if (dim.getByteSize() == 8) { i64 = *(boost::int64_t*)(void*)p; - output = boost::lexical_cast(i64); + output = saturation_cast(i64); } else { throw buffer_error("getField::Unhandled datatype size for SignedInteger"); @@ -295,20 +310,20 @@ inline T PointBuffer::getField(pdal::Dimension const& dim, std::size_t pointInde if (dim.getByteSize() == 1 ) { u8 = *(boost::uint8_t*)(void*)p; - output = boost::lexical_cast(u8); + output = saturation_cast(u8); } else if (dim.getByteSize() == 2) { u16 = *(boost::uint16_t*)(void*)p; - output = boost::lexical_cast(u16); + output = saturation_cast(u16); } else if (dim.getByteSize() == 4) { u32 = *(boost::uint32_t*)(void*)p; - output = boost::lexical_cast(u32); + output = saturation_cast(u32); } else if (dim.getByteSize() == 8) { u64 = *(boost::uint64_t*)(void*)p; - output = boost::lexical_cast(u64); + output = saturation_cast(u64); } else { throw buffer_error("getField::Unhandled datatype size for UnsignedInteger"); @@ -319,11 +334,11 @@ inline T PointBuffer::getField(pdal::Dimension const& dim, std::size_t pointInde if (dim.getByteSize() == 4) { flt = *(float*)(void*)p; - output = boost::lexical_cast(flt); + output = saturation_cast(flt); } else if (dim.getByteSize() == 8) { dbl = *(double*)(void*)p; - output = boost::lexical_cast(dbl); + output = saturation_cast(dbl); } else { throw buffer_error("getField::Unhandled datatype size for Float"); diff --git a/test/data/qfit/20100515_152839.atm4bT2.qi b/test/data/qfit/20100515_152839.atm4bT2.qi new file mode 100644 index 0000000000..131294a68a Binary files /dev/null and b/test/data/qfit/20100515_152839.atm4bT2.qi differ diff --git a/test/data/qfit/pipeline.xml b/test/data/qfit/pipeline.xml new file mode 100644 index 0000000000..b63a360f44 --- /dev/null +++ b/test/data/qfit/pipeline.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/test/unit/QFITReaderTest.cpp b/test/unit/QFITReaderTest.cpp index 85cbd7b886..6b173b3da7 100644 --- a/test/unit/QFITReaderTest.cpp +++ b/test/unit/QFITReaderTest.cpp @@ -39,6 +39,9 @@ #include #include #include +#include +#include +#include #include "Support.hpp" #include @@ -162,6 +165,21 @@ BOOST_AUTO_TEST_CASE(test_14_word) return; } +BOOST_AUTO_TEST_CASE(test_pipeline) +{ + PipelineManager manager; + PipelineReader reader(manager); + + + bool isWriter = reader.readPipeline(Support::datapath("qfit/pipeline.xml")); + BOOST_CHECK_EQUAL(isWriter, true); + + const boost::uint64_t np = manager.execute(); + + BOOST_CHECK_EQUAL(np, 3432); + + return; +} BOOST_AUTO_TEST_SUITE_END()