#include "zlib.h"
#include <fstream>
#include <sstream>
#define CHUNK 32768
bool compress(std::ostream & fout, const std::string & source)
{
int ret, flush = Z_FINISH;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
int level = 6;
int stategy = Z_DEFAULT_STRATEGY; // looks to be the best for .osg/.ive files
//int stategy = Z_FILTERED; //int stategy = Z_HUFFMAN_ONLY; //int stategy = Z_RLE;
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit2(&strm,
level,
Z_DEFLATED,
15 + 16, // +16 to use gzip encoding
8, // default
stategy);
if (ret != Z_OK)
return false;
strm.avail_in = source.size();
strm.next_in = (Bytef*)(&(*source.begin()));
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush); /* no bad return value */
if (ret == Z_STREAM_ERROR)
{
printf("Z_STREAM_ERROR\r\n");
return false;
}
have = CHUNK - strm.avail_out;
if (have>0) fout.write((const char*)out, have);
if (fout.fail())
{
(void)deflateEnd(&strm);
return false;
}
} while (strm.avail_out == 0);
/* clean up and return */
(void)deflateEnd(&strm);
return true;
}
bool uncompress(std::istream & fin, std::string & destination)
{
int ret;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm,
15 + 32 // autodected zlib or gzip header
);
if (ret != Z_OK)
{
printf("failed to init\r\n");
return ret != 0;
}
/* decompress until deflate stream ends or end of file */
do {
//strm.avail_in = fin.readsome((char*)in, CHUNK);
fin.read((char *)in, CHUNK);
strm.avail_in = fin.gcount();
if (strm.avail_in == 0)
{
break;
}
strm.next_in = in;
/* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
switch (ret) {
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return false;
}
have = CHUNK - strm.avail_out;
destination.append((char*)out, have);
} while (strm.avail_out == 0);
/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? true : false;
}
#include <fstream>
#include <sstream>
#define CHUNK 32768
bool compress(std::ostream & fout, const std::string & source)
{
int ret, flush = Z_FINISH;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
int level = 6;
int stategy = Z_DEFAULT_STRATEGY; // looks to be the best for .osg/.ive files
//int stategy = Z_FILTERED; //int stategy = Z_HUFFMAN_ONLY; //int stategy = Z_RLE;
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit2(&strm,
level,
Z_DEFLATED,
15 + 16, // +16 to use gzip encoding
8, // default
stategy);
if (ret != Z_OK)
return false;
strm.avail_in = source.size();
strm.next_in = (Bytef*)(&(*source.begin()));
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush); /* no bad return value */
if (ret == Z_STREAM_ERROR)
{
printf("Z_STREAM_ERROR\r\n");
return false;
}
have = CHUNK - strm.avail_out;
if (have>0) fout.write((const char*)out, have);
if (fout.fail())
{
(void)deflateEnd(&strm);
return false;
}
} while (strm.avail_out == 0);
/* clean up and return */
(void)deflateEnd(&strm);
return true;
}
bool uncompress(std::istream & fin, std::string & destination)
{
int ret;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm,
15 + 32 // autodected zlib or gzip header
);
if (ret != Z_OK)
{
printf("failed to init\r\n");
return ret != 0;
}
/* decompress until deflate stream ends or end of file */
do {
//strm.avail_in = fin.readsome((char*)in, CHUNK);
fin.read((char *)in, CHUNK);
strm.avail_in = fin.gcount();
if (strm.avail_in == 0)
{
break;
}
strm.next_in = in;
/* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
switch (ret) {
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return false;
}
have = CHUNK - strm.avail_out;
destination.append((char*)out, have);
} while (strm.avail_out == 0);
/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? true : false;
}