Skip to content

Instantly share code, notes, and snippets.

@qi7chen
Last active January 18, 2022 01:19
Show Gist options
  • Select an option

  • Save qi7chen/5966371 to your computer and use it in GitHub Desktop.

Select an option

Save qi7chen/5966371 to your computer and use it in GitHub Desktop.
zlib deflate and inflate
typedef std::vector<BYTE> ByteArray;
int CompressByteArray(const ByteArray& input, ByteArray* pOutput)
{
size_t inlen = input.size();
assert(inlen > 0 && pOutput);
/* allocate deflate state */
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.total_in = inlen;
strm.avail_in = inlen;
strm.next_in = (Bytef*)&input[0];
int err = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
if (err != Z_OK)
{
return err;
}
int outlen = deflateBound(&strm, inlen);
pOutput->resize(outlen);
strm.total_out = outlen;
strm.avail_out = outlen;
strm.next_out = (Bytef*)&(*pOutput)[0];
err = deflate(&strm, Z_FINISH);
if (err == Z_STREAM_END)
{
err = Z_OK;
}
deflateEnd(&strm);
return err;
}
int UncompressByteArray(const ByteArray& input, ByteArray* pOutput)
{
size_t inlen = input.size();
assert(inlen > 0 && pOutput);
size_t outlen = pOutput->size();
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.total_in = inlen;
strm.avail_in = inlen;
strm.next_in = (Bytef*)&input[0];
strm.total_out = outlen;
strm.avail_out = outlen;
strm.next_out = (Bytef*)&pOutput[0];
int err = inflateInit(&strm);
if (err != Z_OK)
{
return err;
}
err = inflate(&strm, Z_FINISH);
if (err == Z_STREAM_END)
{
err = Z_OK;
}
inflateEnd(&strm);
return err;
}
bool ReadFileToMemory(const char* filename, ByteArray* pOutput)
{
assert(filename && pOutput);
FILE* fp = fopen(filename, "r");
if (fp == NULL)
{
return false;
}
long length = 0;
fseek(fp, 0, SEEK_END);
length = ftell(fp);
fseek(fp, 0, SEEK_SET);
if (length == 0)
{
return false;
}
pOutput->resize(length);
int bytes = fread(&(*pOutput)[0], sizeof(char), length, fp);
fclose(fp);
return true;
}
int main(int argc, char* argv[])
{
const char* file = "main.cpp";
ByteArray data;
if (!ReadFileToMemory(file, &data))
{
return 1;
}
size_t dataSize = data.size();
printf("raw data size: %d bytes.\n", dataSize);
ByteArray compressed;
int err = CompressByteArray(data, &compressed);
if (err != Z_OK)
{
printf("CompressByteArray() failed: %d .\n", err);
return 1;
}
printf("after compress: %d bytes.\n", compressed.size());
ByteArray uncomp;
uncomp.resize(dataSize);
err = UncompressByteArray(compressed, &uncomp);
if (err != Z_OK)
{
printf("UncompressByteArray() failed: %d .\n", err);
return 1;
}
printf("after uncompress: %d bytes.\n", uncomp.size());
if (data == uncomp)
{
printf("OK.\n");
}
else
{
printf("Failed.\n");
}
return 0;
}
@deleeuwict
Copy link

deleeuwict commented Jan 16, 2022

Ur version of UncompressByteArray function contains 2 errors, =) fixed code below:

int UncompressByteArray(const ByteArray& input, ByteArray* pOutput)
{
	size_t inlen = input.size();
	assert(inlen > 0 && pOutput);
	size_t outlen = pOutput->size();

	z_stream strm;
	strm.zalloc = Z_NULL;
	strm.zfree = Z_NULL;
	strm.opaque = Z_NULL;
	strm.total_in = inlen;
	strm.avail_in = inlen;
	strm.next_in = (Bytef*)&input[0];
	strm.total_out = outlen;
	strm.avail_out = outlen;
	strm.next_out = (Bytef*)&pOutput->at(0); //fixed

	int err = inflateInit(&strm);
	if (err != Z_OK)  //fixed 
	{
		return err;
	}
	err = inflate(&strm, Z_FINISH);
	if (err == Z_STREAM_END)
	{
		err = Z_OK;
	}
	err = inflateEnd(&strm);
	return err;
}

@qi7chen
Copy link
Author

qi7chen commented Jan 18, 2022

thanks, I fixed it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment