mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
fix zstream inflate
This commit is contained in:
parent
147af90897
commit
cdb5139a10
@ -20,8 +20,10 @@
|
|||||||
#include "zStream.h"
|
#include "zStream.h"
|
||||||
#include "filename.h"
|
#include "filename.h"
|
||||||
|
|
||||||
|
#include "zlib.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
decompress(istream &source) {
|
stream_decompress(istream &source) {
|
||||||
IDecompressStream zstream(&source, false);
|
IDecompressStream zstream(&source, false);
|
||||||
|
|
||||||
int ch = zstream.get();
|
int ch = zstream.get();
|
||||||
@ -32,7 +34,7 @@ decompress(istream &source) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
compress(istream &source) {
|
stream_compress(istream &source) {
|
||||||
OCompressStream zstream(&cout, false);
|
OCompressStream zstream(&cout, false);
|
||||||
|
|
||||||
int ch = source.get();
|
int ch = source.get();
|
||||||
@ -42,12 +44,89 @@ compress(istream &source) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zlib_decompress(istream &source) {
|
||||||
|
// First, read the entire contents into a buffer.
|
||||||
|
string data;
|
||||||
|
|
||||||
|
int ch = source.get();
|
||||||
|
while (!source.eof() && !source.fail()) {
|
||||||
|
data += (char)ch;
|
||||||
|
ch = source.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now call zlib to decompress the buffer directly.
|
||||||
|
size_t source_len = data.length();
|
||||||
|
// Take a stab on the appropriate size of the output buffer.
|
||||||
|
size_t dest_len = source_len * 4;
|
||||||
|
char *dest = new char[dest_len];
|
||||||
|
|
||||||
|
uLongf actual_dest_len = dest_len;
|
||||||
|
int result = uncompress((Bytef *)dest, &actual_dest_len,
|
||||||
|
(const Bytef *)data.data(), source_len);
|
||||||
|
if (result != Z_OK) {
|
||||||
|
cerr << "compress result == " << result << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
while (result == Z_BUF_ERROR) {
|
||||||
|
dest_len *= 2;
|
||||||
|
cerr << "Increasing buffer size to " << dest_len << "\n";
|
||||||
|
delete[] dest;
|
||||||
|
dest = new char[dest_len];
|
||||||
|
|
||||||
|
actual_dest_len = dest_len;
|
||||||
|
result = uncompress((Bytef *)dest, &actual_dest_len,
|
||||||
|
(const Bytef *)data.data(), source_len);
|
||||||
|
if (result != Z_OK) {
|
||||||
|
cerr << "compress result == " << result << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cout.write(dest, actual_dest_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zlib_compress(istream &source) {
|
||||||
|
// First, read the entire contents into a buffer.
|
||||||
|
string data;
|
||||||
|
|
||||||
|
int ch = source.get();
|
||||||
|
while (!source.eof() && !source.fail()) {
|
||||||
|
data += (char)ch;
|
||||||
|
ch = source.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now call zlib to compress the buffer directly.
|
||||||
|
size_t source_len = data.length();
|
||||||
|
size_t dest_len = (size_t)(source_len * 1.1) + 12;
|
||||||
|
char *dest = new char[dest_len];
|
||||||
|
|
||||||
|
uLongf actual_dest_len = dest_len;
|
||||||
|
int result = compress((Bytef *)dest, &actual_dest_len,
|
||||||
|
(const Bytef *)data.data(), source_len);
|
||||||
|
|
||||||
|
if (result != Z_OK) {
|
||||||
|
cerr << "compress result == " << result << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
cout.write(dest, actual_dest_len);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[]) {
|
main(int argc, char *argv[]) {
|
||||||
|
bool zlib_direct = false;
|
||||||
|
|
||||||
|
if (argc >= 2 && strcmp(argv[1], "-z") == 0) {
|
||||||
|
zlib_direct = true;
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
cerr << "test_zstream file\n"
|
cerr << "test_zstream [-z] file\n"
|
||||||
<< "compresses file to standard output, or decompresses it if the\n"
|
<< "compresses file to standard output, or decompresses it if the\n"
|
||||||
<< "filename ends in .pz.\n";
|
<< "filename ends in .pz.\n\n"
|
||||||
|
<< "With -z, calls zlib directly instead of using the zstream interface.\n";
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,10 +139,19 @@ main(int argc, char *argv[]) {
|
|||||||
cerr << "Unable to open source " << source_filename << ".\n";
|
cerr << "Unable to open source " << source_filename << ".\n";
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
if (source_filename.get_extension() == "pz") {
|
|
||||||
decompress(source);
|
if (zlib_direct) {
|
||||||
|
if (source_filename.get_extension() == "pz") {
|
||||||
|
zlib_decompress(source);
|
||||||
|
} else {
|
||||||
|
zlib_compress(source);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
compress(source);
|
if (source_filename.get_extension() == "pz") {
|
||||||
|
stream_decompress(source);
|
||||||
|
} else {
|
||||||
|
stream_compress(source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -243,27 +243,21 @@ underflow() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
size_t ZStreamBuf::
|
size_t ZStreamBuf::
|
||||||
read_chars(char *start, size_t length) {
|
read_chars(char *start, size_t length) {
|
||||||
static const size_t decompress_buffer_size = 4096;
|
|
||||||
char decompress_buffer[decompress_buffer_size];
|
|
||||||
|
|
||||||
_z_source.next_out = (Bytef *)start;
|
_z_source.next_out = (Bytef *)start;
|
||||||
_z_source.avail_out = length;
|
_z_source.avail_out = length;
|
||||||
|
|
||||||
int flush = (_source->eof() || _source->fail()) ? Z_FINISH : 0;
|
bool eof = (_source->eof() || _source->fail());
|
||||||
|
|
||||||
while (_z_source.avail_out > 0) {
|
while (_z_source.avail_out > 0) {
|
||||||
if (_z_source.avail_in == 0 && flush == 0) {
|
if (_z_source.avail_in == 0 && !eof) {
|
||||||
_source->read(decompress_buffer, decompress_buffer_size);
|
_source->read(decompress_buffer, decompress_buffer_size);
|
||||||
size_t read_count = _source->gcount();
|
size_t read_count = _source->gcount();
|
||||||
if (read_count == 0 || _source->eof() || _source->fail()) {
|
eof = (read_count == 0 || _source->eof() || _source->fail());
|
||||||
// End of input; tell zlib to expect to stop.
|
|
||||||
flush = Z_FINISH;
|
|
||||||
}
|
|
||||||
|
|
||||||
_z_source.next_in = (Bytef *)decompress_buffer;
|
_z_source.next_in = (Bytef *)decompress_buffer;
|
||||||
_z_source.avail_in = read_count;
|
_z_source.avail_in = read_count;
|
||||||
}
|
}
|
||||||
int result = inflate(&_z_source, flush);
|
int result = inflate(&_z_source, 0);
|
||||||
size_t bytes_read = length - _z_source.avail_out;
|
size_t bytes_read = length - _z_source.avail_out;
|
||||||
|
|
||||||
if (result == Z_STREAM_END) {
|
if (result == Z_STREAM_END) {
|
||||||
|
@ -61,6 +61,20 @@ private:
|
|||||||
|
|
||||||
z_stream _z_source;
|
z_stream _z_source;
|
||||||
z_stream _z_dest;
|
z_stream _z_dest;
|
||||||
|
|
||||||
|
// We need to store the decompression buffer on the class object,
|
||||||
|
// because zlib might not consume all of the input characters at
|
||||||
|
// each call to inflate(). This isn't a problem on output because
|
||||||
|
// in that case we can afford to wait until it does consume all of
|
||||||
|
// the characters we give it.
|
||||||
|
enum {
|
||||||
|
// It's not clear how large or small this buffer ought to be. It
|
||||||
|
// doesn't seem to matter much, especially since this is just a
|
||||||
|
// temporary holding area before getting copied into zlib's own
|
||||||
|
// internal buffers.
|
||||||
|
decompress_buffer_size = 128
|
||||||
|
};
|
||||||
|
char decompress_buffer[decompress_buffer_size];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HAVE_ZLIB
|
#endif // HAVE_ZLIB
|
||||||
|
Loading…
x
Reference in New Issue
Block a user