简体   繁体   English

如何使用 LWJGL 的 LZ4 绑定进行压缩和解压缩

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM