PDA

View Full Version : Uncompress zlib buffer



abshaev
18th February 2016, 15:14
Hello guys!
I am beginning developer in Qt arrived from Delphi community.
In Delphi i used Zlib library for compressing and decompressing buffers allocated in memory.
Now in my Qt project i need to decompress buffer represented by QByteArray, previously compressed by Zlib library.

I try to use
#include <QtZlib/zlib.h>

For example here is my zlib packed buffer

RawDataLen = 50; // length if initial data buffer
CompressedDataLen = 24; // length of zlib compressed data buffer
unsigned char buf[24] = {120, 218, 99, 96, 0, 1, 70, 24, 96, 66, 0, 102, 24, 96, 65, 0, 86, 32, 0, 0, 8, 52, 0, 123}; // Zlib compressed buffer

unsigned long int compressBufLength = CompressedDataLen;
unsigned long int uncompressLength = RawDataLen;

int uncompressValue = uncompress(uncompressBuf,&uncompressLength,buf,compressBufLength); // here i am trying to decompress buffer

But resulted uncompressValue value is 0
What is wrong ?

Lesiok
18th February 2016, 15:26
Use QuaZIP (http://quazip.sourceforge.net/)

abshaev
18th February 2016, 15:30
Us realized QuaZip is good when you work with files on disk. Instead of it i must process buffer in memory.

anda_skoa
18th February 2016, 16:02
But resulted uncompressValue value is 0

Which is good, no?
That is the value of Z_OK, which uncompress returns on success.

Cheers,
_

P.S.: you could also use qUncompress() if you prepend the expected target size as four additional bytes (see documentation of qUncompress)

abshaev
18th February 2016, 17:31
i have succeded by following code:


#include <QtZlib/zlib.h>

unsigned char *compressBuf = new unsigned char[CompressedDataLen];
memcpy(compressBuf, buffer, CompressedDataLen);
unsigned char *uncompressBuf = new unsigned char[RawDataLen];
unsigned long int compressBufLength = CompressedDataLen;
unsigned long int uncompressLength = RawDataLen;
int uncompressValue = uncompress(uncompressBuf, &uncompressLength, compressBuf, compressBufLength);
if (uncompressValue != Z_OK)
{
OutErrorMessage("Uncompression error code " + QString::number(uncompressValue), false);
}
RawData = QByteArray::fromRawData(reinterpret_cast<char*>(uncompressBuf), uncompressLength);


Resulted decompressed buffer lies in uncompressBuf and in RawData

Thank you !

anda_skoa
18th February 2016, 17:42
Why do you copy "buffer" instead of using it as input for uncompress directly?

You probably also want to use a properly sized QByteArray as the uncompressBuffer, unless you really want to do all that memory handling manually.

Cheers,
_

Lesiok
18th February 2016, 18:46
Us realized QuaZip is good when you work with files on disk. Instead of it i must process buffer in memory.
What a problem ? QuaZIP is working with QIODevice so You can use QBuffer.

abshaev
19th February 2016, 09:47
Why do you copy "buffer" instead of using it as input for uncompress directly?

You probably also want to use a properly sized QByteArray as the uncompressBuffer, unless you really want to do all that memory handling manually.

Cheers,
_

Would you please help me to use QByteArray?
When i write:

buffer.resize(CompressedDataLen);
in.readRawData(buffer.data(), buffer.size());
// unsigned char *compressBuf = new unsigned char[CompressedDataLen];
// memcpy(compressBuf, buffer, CompressedDataLen);
unsigned char *uncompressBuf = new unsigned char[RawDataLen];
unsigned long int compressBufLength = CompressedDataLen;
unsigned long int uncompressLength = RawDataLen;
// int uncompressValue = uncompress(uncompressBuf, &uncompressLength, compressBuf, compressBufLength);
int uncompressValue = uncompress(uncompressBuf, &uncompressLength, buffer.data(), compressBufLength);

Error - invalid conversion from 'char' to 'const z_Bytef*' is arrived

also i want that output buffer be represented by QByteArray instead of char buffer

QByteArray RawData;
int uncompressValue = uncompress(RawData.data(), &uncompressLength, buffer.data(), compressBufLength);

How to do it correctly?
Excuse me again, i am currently like a young child in Qt ))

Added after 8 minutes:

Will i have differences in including QuaZip library during moving from windows machine to linux and back ?

anda_skoa
19th February 2016, 13:03
Error - invalid conversion from 'char' to 'const z_Bytef*' is arrived

Strange, as QByteArray::data() returns char* not char.
But you can try casting to what you had before, i.e. unsigned char*


int uncompressValue = uncompress(uncompressBuf, &uncompressLength, static_cast<unsigned char*>(buffer.data()), compressBufLength);




also i want that output buffer be represented by QByteArray instead of char buffer

Right, that is what I meant



QByteArray RawData;
int uncompressValue = uncompress(RawData.data(), &uncompressLength, buffer.data(), compressBufLength);

That will obviously not work since RawData is empty.
You first have to resize it to uncompressedLength, just like you initial did with the manually allocated buffer.

Cheers,
_

abshaev
19th February 2016, 13:46
I did like that:

RawData.resize(RawDataLen);
int uncompressValue = uncompress((Bytef*)RawData.data(), &uncompressLength, (Bytef*)buffer.data(), (uint)CompressedDataLen);

Resulting value of uncompressValue is 0

However i observe some hangups after decompressing procedure. Sometimes Qt-creator crashes after it.
Decompressing data length is about 4 Mb