I am trying to decompress data using the ZLib in iPhone, but it always through error of "Invalid header Check"
.
To compress the data I am using the following in Java
Implementation: Standard Java implementation for Zlib
Deflator : java.util.zip.Deflater
version 1.45, 04/07/06
Compression level: BEST_COMPRESSION
In iPhone the following is the code for decompressing:
- (NSData *)zlibInflate
{
if ([self length] == 0) return self;
unsigned full_length = [self length];
unsigned half_length = [self length] / 2;
NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
BOOL done = NO;
int status;
z_stream strm;
strm.next_in = (Bytef *)[self bytes];
strm.avail_in = [self length];
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if (inflateInit (&strm) != Z_OK) return nil;
while (!done)
{
// Make sure we have enough room and reset the lengths.
if (strm.total_out >= [decompressed length])
[decompressed increaseLengthBy: half_length];
strm.next_out = [decompressed mutableBytes] + strm.total_out;
strm.avail_out = [decompressed length] - strm.total_out;
// Inflate another chunk.
status = inflate (&strm, Z_SYNC_FLUSH);
if (status == Z_STREAM_END) done = YES;
else if (status != Z_OK) {
NSLog(@"%s", strm.msg);
break;
}
}
if (inflateEnd (&strm) != Z_OK) return nil;
// Set real length.
if (done)
{
[decompressed setLength: strm.total_out];
return [NSData dataWithData: decompressed];
}
else return nil;
}
Following is a sample compressed string:
xÚÝUko²Jþ~?ó?¥¾?¤?©?´ÚjCMX,Òµ?ª?µßVX¹È?¿.øë_?¯¶ZÏ%íùxHH&Ã<ÏÌ3ÌÎ
@2.ðE?ºqþpéEzÏ09IoÒ?ª? ?®?£àÌönì$brÛ#fl95?¿»a//Tçáò?¢?¿½
µ©ÊÃÉPÔ¼:8y¦ý.äÎ?µ?¥?¼y?©ã¯9ö?¥½?¢±ÝûwÛ?§ãga?©á8?¨?m\Õ?»6,'Îe?¬}(L}7ÆÅ6#gJ(¥7´s?¬d.ó,Ë°¦prßýÕÖ?
Below is the function for compresser:
public static byte[] compress(String s) {
Deflater comp = new Deflater();
//comp.setLevel(Deflater.BEST_COMPRESSION);
comp.setInput(s.getBytes());
comp.finish();
ByteArrayOutputStream bos = new ByteArrayOutputStream(s.length());
// Compress the data
byte[] buf = new byte[1024];
try {
while (!comp.finished()) {
int count = comp.deflate(buf);
bos.write(buf, 0, count);
}
bos.close();
} catch (Exception e) {
//Log.d(TAG, e.getMessage());
e.printStackTrace();
}
// Get the compressed data
byte[] compressedData = bos.toByteArray();
// put in this fix for Symbol scanners
byte[] compressedDataForSymbol = mungeForSymbol(compressedData);
/*
* byte[] decompressedDataForSymbol =
* decompressedDataAfterSymbol(compressedDataForSymbol); // check they
* are the same for(int i=0;i<compressedData.length;i++) { if
* (compressedData[i] != decompressedDataForSymbol[i]) {
* //System.out.println("Error at " + i); } }
*/
return compressedDataForSymbol;
// return s.getBytes();
}
Using Java Deflater with default compression level creates output encoded data with header with first two bytes 0x78 0x9c. These are not used in IOS. Just remove the first two bytes and try the Inflate ie decompression in IOS. It should work. I had faced the same issue, But i wanted data from IOS(compressed) to android(decompressed).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With