[Liblas-commits] hg-main-tree: non-const fetches of SchemaLayout and Schema to su...

liblas-commits at liblas.org liblas-commits at liblas.org
Wed May 25 18:05:03 EDT 2011


details:   http://hg.libpc.orghg-main-tree/rev/5153948c3c05
changeset: 740:5153948c3c05
user:      Howard Butler <hobu.inc at gmail.com>
date:      Wed May 25 14:51:25 2011 -0500
description:
non-const fetches of SchemaLayout and Schema to support changing a PointBuffer's schema on-the-fly
Subject: hg-main-tree: use standard sequential iterator verbage

details:   http://hg.libpc.orghg-main-tree/rev/0fa58981104e
changeset: 741:0fa58981104e
user:      Howard Butler <hobu.inc at gmail.com>
date:      Wed May 25 14:52:04 2011 -0500
description:
use standard sequential iterator verbage
Subject: hg-main-tree: add non-const getData method to all someone to fiddle with the data directly (like byte swapping it :)

details:   http://hg.libpc.orghg-main-tree/rev/69ff8b3ef58c
changeset: 742:69ff8b3ef58c
user:      Howard Butler <hobu.inc at gmail.com>
date:      Wed May 25 17:03:20 2011 -0500
description:
add non-const getData method to all someone to fiddle with the data directly (like byte swapping it :)
Subject: hg-main-tree: add the generic swap variants as well

details:   http://hg.libpc.orghg-main-tree/rev/c2d70b9b6ef4
changeset: 743:c2d70b9b6ef4
user:      Howard Butler <hobu.inc at gmail.com>
date:      Wed May 25 17:04:16 2011 -0500
description:
add the generic swap variants as well
Subject: hg-main-tree: ByteSwapFilter now seems to work (with tests\!)

details:   http://hg.libpc.orghg-main-tree/rev/b7891eaf18fe
changeset: 744:b7891eaf18fe
user:      Howard Butler <hobu.inc at gmail.com>
date:      Wed May 25 17:04:51 2011 -0500
description:
ByteSwapFilter now seems to work (with tests\!)

diffstat:

 include/libpc/Endian.hpp               |  20 ++++++++
 include/libpc/PointBuffer.hpp          |  17 +++++++
 include/libpc/SchemaLayout.hpp         |   5 ++
 src/filters/ByteSwapFilter.cpp         |  56 +++++++++++++++++++----
 src/filters/ByteSwapFilterIterator.cpp |  52 +++++++++++-----------
 test/unit/ByteSwapFilterTest.cpp       |  77 +++++++++++++++++++++++++++++----
 6 files changed, 180 insertions(+), 47 deletions(-)

diffs (truncated from 329 to 300 lines):

diff -r a2d1322426b1 -r b7891eaf18fe include/libpc/Endian.hpp
--- a/include/libpc/Endian.hpp	Wed May 25 13:58:37 2011 -0500
+++ b/include/libpc/Endian.hpp	Wed May 25 17:04:51 2011 -0500
@@ -88,4 +88,24 @@
             *first = x; \
         }} while(false)
 
+# define SWAP_ENDIANNESS(p) \
+    do { \
+        char* first = static_cast<char*>(static_cast<void*>(&p)); \
+        char* last = first + sizeof(p) - 1; \
+        for(; first < last; ++first, --last) { \
+            char const x = *last; \
+            *last = *first; \
+            *first = x; \
+        }} while(false)
+
+
+# define SWAP_ENDIANNESS_N(p, n) \
+    do { \
+        char* first = static_cast<char*>(static_cast<void*>(&p)); \
+        char* last = first + n - 1; \
+        for(; first < last; ++first, --last) { \
+            char const x = *last; \
+            *last = *first; \
+            *first = x; \
+        }} while(false)
 #endif
diff -r a2d1322426b1 -r b7891eaf18fe include/libpc/PointBuffer.hpp
--- a/include/libpc/PointBuffer.hpp	Wed May 25 13:58:37 2011 -0500
+++ b/include/libpc/PointBuffer.hpp	Wed May 25 17:04:51 2011 -0500
@@ -98,6 +98,18 @@
         return m_schemaLayout.getSchema();
     }
 
+    // schema (number and kinds of fields) for a point in this buffer
+    inline SchemaLayout& getSchemaLayout()
+    {
+        return m_schemaLayout;
+    }
+
+    // convenience function
+    Schema& getSchema() 
+    {
+        return m_schemaLayout.getSchema();
+    }
+    
     // accessors to a particular field of a particular point in this buffer
     template<class T> T getField(std::size_t pointIndex, boost::int32_t fieldIndex) const;
     template<class T> void setField(std::size_t pointIndex, boost::int32_t fieldIndex, T value);
@@ -142,6 +154,11 @@
         return m_data.get() + m_pointSize * pointIndex;
     }
 
+    inline boost::uint8_t* getData(std::size_t pointIndex)
+    {
+        return m_data.get() + m_pointSize * pointIndex;
+    }
+    
     // copy in raw data
     void setData(boost::uint8_t* data, std::size_t pointIndex);
 
diff -r a2d1322426b1 -r b7891eaf18fe include/libpc/SchemaLayout.hpp
--- a/include/libpc/SchemaLayout.hpp	Wed May 25 13:58:37 2011 -0500
+++ b/include/libpc/SchemaLayout.hpp	Wed May 25 17:04:51 2011 -0500
@@ -72,6 +72,11 @@
       return m_schema;
     }
 
+    inline Schema& getSchema() 
+    {
+      return m_schema;
+    }
+    
     /// Fetch total byte size -- sum of all dimensions
     inline std::size_t getByteSize() const
     {
diff -r a2d1322426b1 -r b7891eaf18fe src/filters/ByteSwapFilter.cpp
--- a/src/filters/ByteSwapFilter.cpp	Wed May 25 13:58:37 2011 -0500
+++ b/src/filters/ByteSwapFilter.cpp	Wed May 25 17:04:51 2011 -0500
@@ -37,7 +37,8 @@
 #include <libpc/filters/ByteSwapFilterIterator.hpp>
 #include <libpc/Schema.hpp>
 #include <libpc/PointBuffer.hpp>
-
+#include <libpc/Endian.hpp>
+#include <iostream>
 namespace libpc { namespace filters {
 
 
@@ -45,9 +46,9 @@
     : Filter(prevStage)
 {
 
-    this->setNumPoints(0);
-    this->setPointCountType(PointCount_Unknown);
-
+    this->setNumPoints(prevStage.getNumPoints());
+    this->setPointCountType(prevStage.getPointCountType());
+    
     return;
 }
 
@@ -64,14 +65,46 @@
     return name;
 }
 
-
-
-
-// append all points from src buffer to end of dst buffer, based on the our bounds
 boost::uint32_t ByteSwapFilter::processBuffer(PointBuffer& dstData, const PointBuffer& srcData) const
 {
-    // const SchemaLayout& schemaLayout = dstData.getSchemaLayout();
-    //  const Schema& schema = schemaLayout.getSchema();
+    SchemaLayout& dstSchemaLayout = dstData.getSchemaLayout();
+    Schema & dstSchema = dstSchemaLayout.getSchema();
+    
+    libpc::Schema::Dimensions const& dstDims = dstSchema.getDimensions();
+
+    dstData.copyPointsFast(0, 0, srcData, srcData.getNumPoints());
+    dstData.setNumPoints(srcData.getNumPoints());
+    
+    for (boost::uint32_t i = 0; i != dstData.getNumPoints(); ++i)
+    {
+        boost::uint8_t* data = dstData.getData(i);
+        std::size_t position = 0;
+        for (boost::uint32_t n = 0; n < dstDims.size(); ++n)
+        {
+            Dimension const& d = dstSchema.getDimension(n);
+            std::size_t size = d.getByteSize();
+            
+            boost::uint8_t* pos = data + position;
+            SWAP_ENDIANNESS_N(*pos, size);
+            position = position + size;
+        }
+            
+    }
+    
+
+    for (boost::uint32_t i = 0; i < dstDims.size(); ++i)
+    {
+        Dimension& d = dstSchema.getDimension(i);
+        if (d.getEndianness() == Endian_Little)
+            d.setEndianness(Endian_Big);
+        if (d.getEndianness() == Endian_Big)
+            d.setEndianness(Endian_Little);
+    }
+            
+    
+    
+
+
     // 
     //  int fieldX = schema.getDimensionIndex(Dimension::Field_X, Dimension::Double);
     //  int fieldY = schema.getDimensionIndex(Dimension::Field_Y, Dimension::Double);
@@ -103,7 +136,8 @@
     //  
     //  assert(dstIndex <= dstData.getCapacity());
 
-    return 0;
+    dstData.setNumPoints(dstData.getCapacity());
+    return dstData.getNumPoints();
 }
 
 
diff -r a2d1322426b1 -r b7891eaf18fe src/filters/ByteSwapFilterIterator.cpp
--- a/src/filters/ByteSwapFilterIterator.cpp	Wed May 25 13:58:37 2011 -0500
+++ b/src/filters/ByteSwapFilterIterator.cpp	Wed May 25 17:04:51 2011 -0500
@@ -60,32 +60,34 @@
     // We will read from our previous stage until we get that amount (or
     // until the previous stage runs out of points).
 
-    // boost::uint32_t numPointsNeeded = dstData.getCapacity();
-    // assert(dstData.getNumPoints() == 0);
-    // 
-    // while (numPointsNeeded > 0)
-    // {
-    //     // set up buffer to be filled by prev stage
-    //     PointBuffer srcData(dstData.getSchemaLayout(), numPointsNeeded);
-    // 
-    //     // read from prev stage
-    //     const boost::uint32_t numSrcPointsRead = getPrevIterator().read(srcData);
-    //     assert(numSrcPointsRead == srcData.getNumPoints());
-    //     assert(numSrcPointsRead <= numPointsNeeded);
-    // 
-    //     // we got no data, and there is no more to get -- exit the loop
-    //     if (numSrcPointsRead == 0) break;
-    // 
-    //     // copy points from src (prev stage) into dst (our stage), 
-    //     // based on the CropFilter's rules (i.e. its bounds)
-    //     const boost::uint32_t numPointsProcessed = m_cropFilter.processBuffer(dstData, srcData);
-    // 
-    //     numPointsNeeded -= numPointsProcessed;
-    // }
-    // 
-    // const boost::uint32_t numPointsAchieved = dstData.getNumPoints();
+    boost::uint32_t numPointsNeeded = dstData.getCapacity();
+    assert(dstData.getNumPoints() == 0);
+    
+    while (numPointsNeeded > 0)
+    {
+        // set up buffer to be filled by prev stage
+        PointBuffer srcData(dstData.getSchemaLayout(), numPointsNeeded);
+    
+        // read from prev stage
+        const boost::uint32_t numSrcPointsRead = getPrevIterator().read(srcData);
+        assert(numSrcPointsRead == srcData.getNumPoints());
+        assert(numSrcPointsRead <= numPointsNeeded);
+    
+        // we got no data, and there is no more to get -- exit the loop
+        if (numSrcPointsRead == 0) break;
+    
+        // copy points from src (prev stage) into dst (our stage), 
+        // based on the CropFilter's rules (i.e. its bounds)
+        const boost::uint32_t numPointsProcessed = m_swapFilter.processBuffer(dstData, srcData);
+    
+        numPointsNeeded -= numPointsProcessed;
+    }
+    
+    const boost::uint32_t numPointsAchieved = dstData.getNumPoints();
 
-    return 0;
+    dstData.setNumPoints(dstData.getCapacity());
+
+    return dstData.getCapacity();
 }
 
 
diff -r a2d1322426b1 -r b7891eaf18fe test/unit/ByteSwapFilterTest.cpp
--- a/test/unit/ByteSwapFilterTest.cpp	Wed May 25 13:58:37 2011 -0500
+++ b/test/unit/ByteSwapFilterTest.cpp	Wed May 25 17:04:51 2011 -0500
@@ -34,30 +34,85 @@
 
 #include <boost/test/unit_test.hpp>
 #include <boost/cstdint.hpp>
+#include <libpc/Endian.hpp>
 
 #include <libpc/drivers/faux/Reader.hpp>
 #include <libpc/drivers/faux/Writer.hpp>
 #include <libpc/filters/ByteSwapFilter.hpp>
 
+#include <boost/scoped_ptr.hpp>
+#include <libpc/PointBuffer.hpp>
+#include <libpc/Endian.hpp>
+#include <iostream>
+
 using namespace libpc;
 
 BOOST_AUTO_TEST_SUITE(ByteSwapFilterTest)
 
-BOOST_AUTO_TEST_CASE(test_crop)
+BOOST_AUTO_TEST_CASE(test_swapping)
 {
     Bounds<double> srcBounds(0.0, 0.0, 0.0, 10.0, 100.0, 1000.0);
+    
+    boost::uint32_t buffer_size = 20;
+    libpc::drivers::faux::Reader reader(srcBounds, buffer_size, libpc::drivers::faux::Reader::Ramp);
 
-    // crop the window to 1/3rd the size in each dimension
-    Bounds<double> dstBounds(3.33333, 33.33333, 333.33333, 6.66666, 66.66666, 666.66666);
+    libpc::filters::ByteSwapFilter filter(reader);
+    BOOST_CHECK_EQUAL(filter.getName(), "filters.byteswap");
+
+    boost::scoped_ptr<SequentialIterator> unflipped_iter(reader.createSequentialIterator());
+    boost::scoped_ptr<SequentialIterator> flipped_iter(filter.createSequentialIterator());
+
+    const Schema& schema = reader.getSchema();
     
-    libpc::drivers::faux::Reader reader(srcBounds, 1000, libpc::drivers::faux::Reader::Ramp);
-    // 
-    // libpc::filters::CropFilter filter(reader, dstBounds);
-    // BOOST_CHECK(filter.getDescription() == "Crop Filter");
-    // 
-    // libpc::drivers::faux::Writer writer(filter);
-    // 
-    // boost::uint64_t numWritten = writer.write(1000);
+    PointBuffer flipped(filter.getSchema(), buffer_size);
+    const boost::uint32_t fliped_read = flipped_iter->read(flipped);
+    BOOST_CHECK_EQUAL(fliped_read, buffer_size);
+
+    PointBuffer unflipped(schema, buffer_size);
+    const boost::uint32_t unfliped_read = unflipped_iter->read(unflipped);
+    BOOST_CHECK_EQUAL(unfliped_read, buffer_size);
+    
+
+    int offsetX = schema.getDimensionIndex(Dimension::Field_X, Dimension::Double);
+    int offsetY = schema.getDimensionIndex(Dimension::Field_Y, Dimension::Double);
+    int offsetZ = schema.getDimensionIndex(Dimension::Field_Z, Dimension::Double);
+    int offsetT = schema.getDimensionIndex(Dimension::Field_Time, Dimension::Uint64);
+    
+    BOOST_CHECK_EQUAL(offsetX, 0);
+    BOOST_CHECK_EQUAL(offsetY, 1);
+    BOOST_CHECK_EQUAL(offsetZ, 2);
+    BOOST_CHECK_EQUAL(offsetT, 3);
+    
+    for (boost::uint32_t i = 0 ; i < buffer_size; ++i)
+    {
+
+        double unflipped_x = unflipped.getField<double>(i, offsetX);


More information about the Liblas-commits mailing list