Moved compress/uncompress code across to using gzip compatible methods
This commit is contained in:
parent
46172c931e
commit
d8525815fd
@ -103,6 +103,11 @@ class ReaderWriterGZ : public osgDB::ReaderWriter
|
||||
|
||||
WriteResult writeFile(ObjectType objectType, const osg::Object* object, const std::string& fullFileName, const osgDB::ReaderWriter::Options* options) const;
|
||||
|
||||
|
||||
bool read(std::istream& fin, std::string& destination) const;
|
||||
bool write(std::ostream& fout, const std::string& source) const;
|
||||
|
||||
|
||||
};
|
||||
|
||||
ReaderWriterGZ::ReaderWriterGZ()
|
||||
@ -169,30 +174,9 @@ osgDB::ReaderWriter::ReadResult ReaderWriterGZ::readFile(ObjectType objectType,
|
||||
std::ifstream fin(fileName.c_str());
|
||||
if (!fin) return ReadResult::ERROR_IN_READING_FILE;
|
||||
|
||||
std::streampos start = fin.tellg();
|
||||
fin.seekg(0, std::ios::end);
|
||||
std::streampos end = fin.tellg();
|
||||
fin.seekg(start, std::ios::beg);
|
||||
std::streampos sourceLen = end - start;
|
||||
|
||||
/* empty stream into memory, open that, and keep the pointer in a FreeTypeFont for cleanup */
|
||||
char* buffer = new char[sourceLen];
|
||||
fin.read(reinterpret_cast<char*>(buffer), sourceLen);
|
||||
if (!fin || (static_cast<std::streampos>(fin.gcount()) != sourceLen))
|
||||
{
|
||||
osg::notify(osg::WARN)<<" .... the compressed file could not be read from its stream"<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uLongf destLen = 1000000;
|
||||
|
||||
std::string dest;
|
||||
dest.resize(destLen);
|
||||
|
||||
int result = uncompress ((Bytef *)(&(*dest.begin())), &destLen,
|
||||
(const Bytef *)buffer, sourceLen);
|
||||
|
||||
delete [] buffer;
|
||||
read(fin, dest);
|
||||
|
||||
std::stringstream strstream(dest);
|
||||
|
||||
@ -241,35 +225,137 @@ osgDB::ReaderWriter::WriteResult ReaderWriterGZ::writeFile(ObjectType objectType
|
||||
std::stringstream strstream;
|
||||
osgDB::ReaderWriter::WriteResult writeResult = writeFile(objectType, object, rw, strstream, options);
|
||||
|
||||
std::ofstream fout(fullFileName.c_str());
|
||||
|
||||
std::string str(strstream.str());
|
||||
write(fout,strstream.str());
|
||||
|
||||
uLong destLen = compressBound(str.size());
|
||||
|
||||
osg::notify(osg::NOTICE)<<"compressBound("<<str.size()<<") = "<<destLen<<std::endl;
|
||||
|
||||
std::string output;
|
||||
output.resize(destLen);
|
||||
|
||||
int level = 6;
|
||||
|
||||
char* source = new char[str.size()];
|
||||
char* dest = new char[destLen];
|
||||
|
||||
int result = compress2( (Bytef *)(&(*output.begin())), &destLen,
|
||||
(const Bytef *)(&(*str.begin())), str.size(),
|
||||
level);
|
||||
|
||||
osg::notify(osg::NOTICE)<<"compress2()"<<result<<", destLen="<<destLen<<std::endl;
|
||||
|
||||
output.resize(destLen);
|
||||
|
||||
std::ofstream fout(fullFileName.c_str());
|
||||
fout<<output;
|
||||
|
||||
return writeResult;
|
||||
}
|
||||
|
||||
#define CHUNK 16384
|
||||
|
||||
bool ReaderWriterGZ::read(std::istream& fin, std::string& destination) const
|
||||
{
|
||||
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)
|
||||
return ret;
|
||||
|
||||
/* decompress until deflate stream ends or end of file */
|
||||
do {
|
||||
|
||||
osg::notify(osg::NOTICE)<<"Doing readsome"<<std::endl;
|
||||
|
||||
strm.avail_in = fin.readsome((char*)in, CHUNK);
|
||||
|
||||
if (fin.fail())
|
||||
{
|
||||
(void)inflateEnd(&strm);
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
bool ReaderWriterGZ::write(std::ostream& fout, const std::string& source) const
|
||||
{
|
||||
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)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Z_STREAM_ERROR"<<std::endl;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// now register with Registry to instantiate the above
|
||||
// reader/writer.
|
||||
REGISTER_OSGPLUGIN(GZ, ReaderWriterGZ)
|
||||
|
Loading…
Reference in New Issue
Block a user