We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I made this code to compress a multidimensional float array to a compressed base64 string:
import java.util.zip.Deflater;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.Base64;
import java.lang.*;
// compress
void setup() {
//
float[][] xy_array = new float[][] {{1, 2}, {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {1, 2}, {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {1, 2}, {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {1, 2}, {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {1, 2}, {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}};
Deflater compresser = new Deflater(Deflater.BEST_COMPRESSION);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ByteBuffer byteBuffer = ByteBuffer.allocate(8);
try {
for (float[] xy : xy_array) {
byteBuffer.clear();
byteBuffer.putFloat(xy[0]);
byteBuffer.putFloat(xy[1]);
byteStream.write(byteBuffer.array());
}
}
catch (IOException e) {
println(e);
}
byte[] bytes = byteStream.toByteArray();
compresser.setInput(bytes);
compresser.finish();
byte[] output_buffer = new byte[bytes.length];
int compressed_data_length = compresser.deflate(output_buffer);
compresser.end();
byte[] buffer = new byte[compressed_data_length];
System.arraycopy(output_buffer, 0, buffer, 0, compressed_data_length);
String s = Base64.getEncoder().encodeToString(buffer);
println(s); // eNqzb2BgcGCAYiDhAOIvAOIDQPyAgcERKO4oAMQKQGzAwGA/xNUDAGh4InA=
}
I try to unpack that String. This is work in progress but I can't figure out what leads to the error. It might be even the packer above...
The error I get is:
java.util.zip.DataFormatException: incorrect header check
I hope someone can help.
import java.util.zip.Inflater;
void setup() {
String s = "eNqzb2BgcGCAYiDhAOIvAOIDQPyAgcERKO4oAMQKQGzAwGA/xNUDAGh4InA=";
byte[] input = null;
try {
input = s.getBytes("UTF-8");
}
catch (Exception e) {
println(e);
}
if (input == null) return;
Inflater decompresser = new Inflater();
decompresser.setInput(input);
byte[] result = new byte[input.length];
try {
int resultLength = decompresser.inflate(result);
}
catch (Exception e) {
println(e);
}
decompresser.end();
}
Answers
i'd try this one bit at a time
START with a readable string as input data rather than byte encoded floats. this'll make it easier to debug.
then either zip that and save the zip file (you should be able to unzip this using command line tools)
or base64 encode this and save the result (you should also be able to base64 decode this on the command line)
when both those are working then you can zip + base64 encode together
There are 2 major mistakes in the second sketch (decompressor)
1) You don't Base64 decode the string first
2) You set the buffer size equal to the length of the encoded string i.e. the compressed data.
The following sketch provides two methods to encode-the-array and decode-the-string
Thanks @quark . I noticed today when being more awake.
I just solved it before getting here. It's really inefficient with creating new arrays of the correct size all the time but it made the code a bit more clear to me to find the problem.
I will look at your code later when I have time (next week...)