#ifdef USE_ZLIB
void Compression::CompressStreamToFile(const Vector<BYTE> &stream, const String &filename)
{
CompressStreamToFile(stream.CArray(), stream.Length(), filename);
}
void Compression::CompressStreamToFile(const BYTE *stream, UINT byteCount, const String &filename)
{
BYTE *compressedStream = new BYTE[byteCount + 64];
z_stream zstream;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
zstream.avail_in = byteCount;
zstream.next_in = const_cast<BYTE*>(stream);
zstream.data_type = Z_BINARY;
zstream.avail_out = byteCount + 64;
zstream.next_out = compressedStream;
const int Level = 6;
int result = deflateInit2(&zstream, Level, Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY);
PersistentAssert(result == Z_OK, "deflateInit failed");
result = deflate(&zstream, Z_FINISH);
PersistentAssert(result == Z_STREAM_END, "deflate failed");
deflateEnd(&zstream);
FILE *file = Utility::CheckedFOpen(filename.CString(), "wb");
Utility::CheckedFWrite(&byteCount, sizeof(UINT32), 1, file);
Utility::CheckedFWrite(compressedStream, sizeof(BYTE), zstream.total_out, file);
fclose(file);
delete[] compressedStream;
}
void Compression::DecompressStreamFromFile(const String &filename, Vector<BYTE> &stream)
{
Vector<BYTE> input;
Utility::GetFileData(filename, input);
UINT32 decompressedByteCount = ((UINT32*)input.CArray())[0];
stream.Allocate(decompressedByteCount);
uLongf finalByteCount = decompressedByteCount;
int result = uncompress(stream.CArray(), &finalByteCount, input.CArray() + sizeof(UINT32), input.Length() - sizeof(UINT32));
PersistentAssert(result == Z_OK, "Decompression failed");
PersistentAssert(finalByteCount == decompressedByteCount, "Decompression returned invalid length");
}
#else
void Compression::CompressStreamToFile(const Vector<BYTE> &stream, const String &filename)
{
SignalError("Must define USE_ZLIB to use compression functions");
}
void Compression::CompressStreamToFile(const BYTE *stream, UINT byteCount, const String &filename)
{
SignalError("Must define USE_ZLIB to use compression functions");
}
void Compression::DecompressStreamFromFile(const String &filename, Vector<BYTE> &stream)
{
SignalError("Must define USE_ZLIB to use compression functions");
}
#endif