[英]How to use LWJGL's LZ4 bindings to compress and decompress
I am attempting to create two helper methods, one to compress and one to decompress.我正在尝试创建两种辅助方法,一种用于压缩,一种用于解压缩。 These methods should use LWJGL's LZ4 bindings to accomplish the compression/decompression.
这些方法应该使用 LWJGL 的 LZ4 绑定来完成压缩/解压缩。
They mostly work already but the byte array that get's returned after decompressing has trailing zeros.它们大多已经工作,但解压后返回的字节数组有尾随零。
import static org.lwjgl.util.lz4.LZ4.LZ4_compressBound;
import static org.lwjgl.util.lz4.LZ4.LZ4_compress_default;
import static org.lwjgl.util.lz4.LZ4.LZ4_decompress_safe;
import java.nio.ByteBuffer;
public static byte[] compress(byte[] data) {
ByteBuffer buffer = BufferUtils.createByteBuffer(data.length);
for (int i = 0; i < data.length; i++) {
buffer.put(data[i]);
}
buffer.flip();
ByteBuffer destination = BufferUtils.createByteBuffer(LZ4_compressBound(buffer.remaining()));
destination.clear();
LZ4_compress_default(buffer, destination);
return getByteArrayFromByteBuffer(destination);
}
public static byte[] decompress(byte[] data) {
ByteBuffer buffer = BufferUtils.createByteBuffer(data.length);
for (int i = 0; i < data.length; i++) {
buffer.put(data[i]);
}
buffer.flip();
ByteBuffer destination = BufferUtils.createByteBuffer(LZ4_compressBound(buffer.remaining()));
destination.clear();
LZ4_decompress_safe(buffer, destination);
return getByteArrayFromByteBuffer(destination);
}
public static byte[] getByteArrayFromByteBuffer(ByteBuffer byteBuffer) {
byte[] bytesArray = new byte[byteBuffer.remaining()];
byteBuffer.get(bytesArray, 0, bytesArray.length);
return bytesArray;
}
The result after running compress(decompress(SOME DATA)), is: [SOME_DATA, 0, 0, 0].运行 compress(decompress(SOME DATA)) 后的结果是:[SOME_DATA, 0, 0, 0]。
The first half of the data is correct but for some reason extra zeros are added.数据的前半部分是正确的,但由于某种原因添加了额外的零。 This is probably due to the ByteBuffers not being correctly setup, but I am unsure.
这可能是由于 ByteBuffers 没有正确设置,但我不确定。 Either way how can I remove these extra zeros?
无论哪种方式,我如何删除这些额外的零?
Also unfortunately this is the only link I could find that shows an example on how this is supposed to work.同样不幸的是, 这是我能找到的唯一一个链接,它显示了一个关于它应该如何工作的例子。
First of all, during compression you are currently using the result of LZ4_compressBound(...)
to define the initial capacity of your destination buffer.首先,在压缩期间,您当前使用
LZ4_compressBound(...)
的结果来定义目标缓冲区的初始容量。 While this is correct, you have to keep in mind that this is only the Worst-Case size of the compressed data.虽然这是正确的,但您必须记住,这只是压缩数据的最坏情况大小。 The actual amount of bytes written by
LZ4_compress_default(...)
is the return value of said function and likely less than the bound. LZ4_compress_default(...)
写入的实际字节数是所述函数的返回值,可能小于界限。 Thus you need to trim your destination buffer to match that size.因此,您需要修剪目标缓冲区以匹配该大小。
int compressedSize = LZ4_compress_default(buffer, destination);
destination.limit(compressedSize);
destination = destination.slice();
Additionally you have a similar bug in your decompression: You can not use LZ4_compressBound(...)
to calculate the capacity of your destination buffer.此外,您在解压中也有一个类似的错误:您不能使用
LZ4_compressBound(...)
来计算目标缓冲区的容量。 Instead, you need to store the size of the decompressed data elsewhere.相反,您需要将解压缩数据的大小存储在别处。 (In theory you could use
compressedSize * 255
but this is extremely impractial since that compression ratio is almost never achieved and thus leads to a huge amount of wasted resources. See here. ) And again you need to respect the return value of LZ4_decompress_safe
which is the actual size of the decompressed data. (理论上你可以使用
compressedSize * 255
但这是非常不切实际的,因为压缩率几乎从未达到,从而导致大量资源浪费。见这里。 )再次你需要尊重LZ4_decompress_safe
的返回值,它是解压数据的实际大小。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.