Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix entropy range encoding in octree-based pointcloud compression #3579

Merged

Conversation

nicolas-cadart
Copy link
Contributor

Error description

Octree Pointcloud compression encoding was faulty when pointcloud had 2^i - 3 points (problem was spotted with 253 points), leading to program crash when decoding the wrongly encoded compressed data.

Error origin

The crash comes from a division by zero in pcl::StaticRangeCoder::decodeStreamToIntVector(), when frequency element value is read as 0 instead of 2^i. In fact, this frequency value is badly written in pcl::StaticRangeCoder::encodeIntVectorToStream() because bytes size of each frequency element is wrongly computed.

For example, with n = 253 points, last frequency element is equal to 256. This value needs 2 bytes to be encoded. However, frequencyTableByteSize was set to 1 byte for this border case. As a result, only the 'null' byte was written to compressed data, missing the most significant one : this frequency element value is written as 0 instead of 256.

Proposed correction

The frequencyTableByteSize is now corrected to consider this border case. No change occurs for other pointclouds sizes.

@kunaltyagi
Copy link
Member

kunaltyagi commented Jan 21, 2020

@nicolas-cadart Thanks for the fix! Is it possible to provide a test case too? It'll prevent regressions. The tests are located in test/io/test_range_coder.cpp

Maybe reorder the commits so that the tests come before the fix.

@nicolas-cadart
Copy link
Contributor Author

@nicolas-cadart Thanks for the fix! Is it possible to provide a test case too? It'll prevent regressions. The tests are located in test/io/test_range_coder.cpp

Maybe reorder the commits so that the tests come before the fix.

I modified the test to deal with a problematic size. This test fails without the fix, and is OK with it.

Copy link
Member

@kunaltyagi kunaltyagi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please reorder the commits and it's a go 🚀

You can use git rebase -i master and then swap the first two lines around. Here master is the branch on top of which you've applied the fix

test/io/test_range_coder.cpp Show resolved Hide resolved
Copy link
Member

@taketwo taketwo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for contributing!

Size of frequency table elements was wrongly computed when frequency was a power of 2.
This led to faulty frequency table encoding with 1 missing byte.
During decoding, the frequency was decoded to 0 as 1 byte is missing, leading to
division by 0 and thus error.

The frequencyTableByteSize is now correctly computed.
@nicolas-cadart nicolas-cadart force-pushed the fix/octreeCompressionEncoding branch from 2cabb11 to 0aaa6ac Compare January 22, 2020 07:52
@nicolas-cadart
Copy link
Contributor Author

Please reorder the commits and it's a go rocket

Done ! ;)

@kunaltyagi kunaltyagi merged commit 8ed756f into PointCloudLibrary:master Jan 22, 2020
@taketwo taketwo added the changelog: fix Meta-information for changelog generation label Mar 17, 2020
@taketwo taketwo changed the title Fix entropy range encoding in octree pointcloud compression Fix entropy range encoding in octree-based pointcloud compression Mar 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog: fix Meta-information for changelog generation module: io
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants