-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
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
Fix entropy range encoding in octree-based pointcloud compression #3579
Conversation
@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. |
There was a problem hiding this 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
There was a problem hiding this 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.
2cabb11
to
0aaa6ac
Compare
Done ! ;) |
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 inpcl::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.