pierrec / node-lz4

LZ4 fast compression algorithm for NodeJS
MIT License
438 stars 98 forks source link

Decompressing Byte-Array Compressed With python-lz4 #108

Closed Dospacite closed 3 years ago

Dospacite commented 3 years ago

I'm trying to decompress a byte array in JavaScript with lz4. I tried to implement the example in the npmjs page. I already have the data in compressed format, thus compressing it again leads to unwanted results. I have tried:

var input = Buffer.from(this.bytes);
var output = Buffer.alloc( lz4.encodeBound(input.length) );
var uncompressed = Buffer.alloc(input.length);
var uncompressedSize = lz4.decodeBlock(output, uncompressed);
uncompressed = uncompressed.slice(0, uncompressedSize);

console.log( "uncompressed data", uncompressed);

Which leads to an array of 0's. I have confirmed that the data I pass (this.bytes) is a valid array of bytes. Ex: [f1,09,01,54,00,00,00,00,46,00,00,00,53,07,00,00,00,6f,66,66,73,65,74,58,4e,00,01,00,f1,35,2a,c0,53,08,00,00,00,69,74,65,6d,49,63,6f,6e,53,1f,00,00,00,57,65,61,70,6f,6e,45,6e,63,68,61,6e,74,6d,65,6e,74,5f,53,70,65,61,72,30,32,5f,4c,61,72,67,65,53,0b,00,00,00,53,63,72,65,65,6e,57,69,64,74,68,4e,49,00,55,00,9e,40,53,06,5f,00,01,73,00,f1,04,02,00,00,00,53,01,00]

console.log(LZ4.decode(this.bytes.join(""))); This leads to this error:

Uncaught (in promise) Error: Invalid magic number: 39303166 @0
emit_Error http://localhost:8080/javascripts/lz4.min.js:8
read_MagicNumber http://localhost:8080/javascripts/lz4.min.js:8
_main http://localhost:8080/javascripts/lz4.min.js:8
_transform http://localhost:8080/javascripts/lz4.min.js:8
_read http://localhost:8080/javascripts/lz4.min.js:8
_write http://localhost:8080/javascripts/lz4.min.js:8
b http://localhost:8080/javascripts/lz4.min.js:8
s http://localhost:8080/javascripts/lz4.min.js:8
write http://localhost:8080/javascripts/lz4.min.js:8
end http://localhost:8080/javascripts/lz4.min.js:8
LZ4_uncompress http://localhost:8080/javascripts/lz4.min.js:8
construct http://localhost:8080/javascripts/readSaveFile.js:194

Upon researching this issue, I came across this issue. I could not find the function lz4.createDecoderStream.prototype.uncompressBlock I then tried an example from the node-lz4 github repo:

var compressed = Buffer.from(this.lua_state);
var uncompressedBlock = Buffer.alloc(compressed.length*10);
var n = LZ4.decodeBlock(compressed, uncompressedBlock);
uncompressedBlock = uncompressedBlock.slice(0,n);
console.log(uncompressedBlock);

Which returns, you guessed it, an array of 0's.

Dospacite commented 3 years ago

The problem was that my input array was not an array of integers, so I just converted it into an UInt8Array with this function:

function convert_byte_array_to_int_array(array) {
     let output_array = [];
     array.forEach(byte => {
         output_array.push(parseInt(byte, 16));
     });
     return output_array;
}

And used it in the package's example like this:

var input = convert_byte_array_to_int_array(this.bytes);
console.log(input);
var uncompressed = Buffer.alloc(input.length);
var uncompressedSize = LZ4.decodeBlock(input, uncompressed);
uncompressed = uncompressed.slice(0, uncompressedSize);

console.log( "uncompressed data", uncompressed );

Uncompressed data that was output to the console was the data I was looking for. Thank you for your help.