mirror of
https://github.com/AssetRipper/lzham_codec.git
synced 2026-11-13 18:07:24 -10:00
235 lines
6.3 KiB
C++
235 lines
6.3 KiB
C++
// example3.cpp - Tests streaming and random access packet compression using the compressor's LZHAM_Z_FULL_FLUSH flush mode, and the
|
|
// decompressor's LZHAM_Z_SYNC_FLUSH flush mode.
|
|
// This example statically links against lzhamlib, lzhamcomp, and lzhamdecomp libs.
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <memory.h>
|
|
#include <vector>
|
|
|
|
// Define LZHAM_DEFINE_ZLIB_API causes lzham.h to remap the zlib.h functions/macro definitions to lzham's.
|
|
// This is totally optional - you can also directly use the lzham_* functions and macros instead.
|
|
#define LZHAM_DEFINE_ZLIB_API
|
|
#include "lzham_static_lib.h"
|
|
|
|
typedef unsigned char uint8;
|
|
typedef unsigned short uint16;
|
|
typedef unsigned int uint;
|
|
|
|
#define my_max(a,b) (((a) > (b)) ? (a) : (b))
|
|
#define my_min(a,b) (((a) < (b)) ? (a) : (b))
|
|
|
|
#define BUF_SIZE (1024 * 1024)
|
|
static uint8 s_inbuf[BUF_SIZE];
|
|
static uint8 s_outbuf[BUF_SIZE];
|
|
|
|
#define WINDOW_BITS 20
|
|
|
|
// Tests
|
|
static bool sequential_test()
|
|
{
|
|
printf("Sequential record/packet decompression test:\n");
|
|
|
|
z_stream stream;
|
|
memset(&stream, 0, sizeof(stream));
|
|
stream.next_in = s_inbuf;
|
|
stream.avail_in = 0;
|
|
stream.next_out = s_outbuf;
|
|
stream.avail_out = BUF_SIZE;
|
|
|
|
if (deflateInit2(&stream, Z_BEST_COMPRESSION, LZHAM_Z_LZHAM, WINDOW_BITS, 9, Z_DEFAULT_STRATEGY) != Z_OK)
|
|
return false;
|
|
|
|
std::vector<uint8> comp_buf;
|
|
const uint cRecordSize = 128;
|
|
|
|
for (uint i = 0; i < 1000; i++)
|
|
{
|
|
memset(s_inbuf, 0, 128);
|
|
sprintf((char*)s_inbuf, "%u, %u, %u, %u, This is a testThis is a testThis is a testThis is a testThis is a test\n", i, i, i, i);
|
|
|
|
stream.next_in = s_inbuf;
|
|
stream.avail_in = cRecordSize;
|
|
|
|
while (stream.avail_in)
|
|
{
|
|
stream.next_out = s_outbuf;
|
|
stream.avail_out = BUF_SIZE;
|
|
|
|
if (deflate(&stream, Z_FULL_FLUSH) != Z_OK)
|
|
{
|
|
deflateEnd(&stream);
|
|
return false;
|
|
}
|
|
|
|
comp_buf.insert(comp_buf.end(), s_outbuf, s_outbuf + (BUF_SIZE - stream.avail_out));
|
|
}
|
|
|
|
printf("Compressing record %u and flushing compressor, %u bytes\n", i, stream.total_out);
|
|
}
|
|
|
|
stream.avail_in = 0;
|
|
for ( ; ; )
|
|
{
|
|
stream.next_out = s_outbuf;
|
|
stream.avail_out = BUF_SIZE;
|
|
int status = deflate(&stream, Z_FINISH);
|
|
|
|
comp_buf.insert(comp_buf.end(), s_outbuf, s_outbuf + (BUF_SIZE - stream.avail_out));
|
|
|
|
if (status == Z_STREAM_END)
|
|
break;
|
|
else if (status != Z_OK)
|
|
{
|
|
deflateEnd(&stream);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
deflateEnd(&stream);
|
|
|
|
memset(&stream, 0, sizeof(stream));
|
|
stream.next_in = &comp_buf[0];
|
|
stream.avail_in = (uint)comp_buf.size();
|
|
stream.next_out = s_outbuf;
|
|
stream.avail_out = BUF_SIZE;
|
|
|
|
if (inflateInit2(&stream, WINDOW_BITS) != Z_OK)
|
|
return false;
|
|
|
|
for (uint i = 0; i < 1000; i++)
|
|
{
|
|
stream.next_out = s_outbuf;
|
|
stream.avail_out = cRecordSize;
|
|
|
|
int status = inflate(&stream, Z_SYNC_FLUSH);
|
|
if (status == Z_STREAM_END)
|
|
break;
|
|
if (status != Z_OK)
|
|
{
|
|
inflateEnd(&stream);
|
|
return false;
|
|
}
|
|
|
|
memset(s_inbuf, 0, 128);
|
|
sprintf((char*)s_inbuf, "%u, %u, %u, %u, This is a testThis is a testThis is a testThis is a testThis is a test\n", i, i, i, i);
|
|
if (memcmp(s_inbuf, s_outbuf, cRecordSize) != 0)
|
|
return false;
|
|
|
|
printf("Successfully decompressed record %u\n", i);
|
|
}
|
|
|
|
inflateEnd(&stream);
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool random_test()
|
|
{
|
|
printf("Random record/packet decompression test:\n");
|
|
|
|
z_stream stream;
|
|
memset(&stream, 0, sizeof(stream));
|
|
stream.next_in = s_inbuf;
|
|
stream.avail_in = 0;
|
|
stream.next_out = s_outbuf;
|
|
stream.avail_out = BUF_SIZE;
|
|
|
|
if (deflateInit2(&stream, Z_BEST_COMPRESSION, LZHAM_Z_LZHAM, WINDOW_BITS, 9, Z_DEFAULT_STRATEGY) != Z_OK)
|
|
return false;
|
|
|
|
const uint cTotalRecords = 200;
|
|
std::vector< std::vector<uint8> > comp_bufs(cTotalRecords);
|
|
|
|
const uint cRecordSize = 128;
|
|
|
|
for (uint i = 0; i < cTotalRecords; i++)
|
|
{
|
|
memset(s_inbuf, 0, 128);
|
|
sprintf((char*)s_inbuf, "%u, %u, %u, %u, This is a testThis is a testThis is a testThis is a testThis is a test\n", i, i, i, i);
|
|
|
|
stream.next_in = s_inbuf;
|
|
stream.avail_in = cRecordSize;
|
|
|
|
while (stream.avail_in)
|
|
{
|
|
stream.next_out = s_outbuf;
|
|
stream.avail_out = BUF_SIZE;
|
|
|
|
if (deflate(&stream, Z_FULL_FLUSH) != Z_OK)
|
|
{
|
|
deflateEnd(&stream);
|
|
return false;
|
|
}
|
|
|
|
comp_bufs[i].insert(comp_bufs[i].end(), s_outbuf, s_outbuf + (BUF_SIZE - stream.avail_out));
|
|
}
|
|
|
|
printf("Compressing record %u and flushing compressor, %u bytes\n", i, stream.total_out);
|
|
}
|
|
|
|
deflateEnd(&stream);
|
|
|
|
memset(&stream, 0, sizeof(stream));
|
|
stream.next_in = &(comp_bufs[0])[0];
|
|
stream.avail_in = (uint)comp_bufs[0].size();
|
|
stream.next_out = s_outbuf;
|
|
stream.avail_out = BUF_SIZE;
|
|
|
|
if (inflateInit2(&stream, WINDOW_BITS) != Z_OK)
|
|
return false;
|
|
|
|
for (uint i = 0; i < cTotalRecords * 2; i++)
|
|
{
|
|
uint rec_index = 0;
|
|
if (i)
|
|
rec_index = (rand() % (cTotalRecords - 1)) + 1;
|
|
|
|
stream.next_in = &(comp_bufs[rec_index])[0];
|
|
stream.avail_in = (uint)comp_bufs[rec_index].size();
|
|
stream.next_out = s_outbuf;
|
|
stream.avail_out = cRecordSize;
|
|
|
|
int status = inflate(&stream, Z_SYNC_FLUSH);
|
|
if (status == Z_STREAM_END)
|
|
break;
|
|
if (status != Z_OK)
|
|
{
|
|
inflateEnd(&stream);
|
|
return false;
|
|
}
|
|
|
|
memset(s_inbuf, 0, 128);
|
|
sprintf((char*)s_inbuf, "%u, %u, %u, %u, This is a testThis is a testThis is a testThis is a testThis is a test\n", rec_index, rec_index, rec_index, rec_index);
|
|
if (memcmp(s_inbuf, s_outbuf, cRecordSize) != 0)
|
|
return false;
|
|
|
|
printf("Successfully decompressed random record %u\n", rec_index);
|
|
}
|
|
|
|
inflateEnd(&stream);
|
|
|
|
return true;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
argc, argv;
|
|
printf("LZHAM example3 (single function call compression/decompression with flushing)\nUsing library version: %s\n", ZLIB_VERSION);
|
|
|
|
if (!sequential_test())
|
|
{
|
|
printf("Sequential test failed!\n");
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
if (!random_test())
|
|
{
|
|
printf("Random test failed!\n");
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
printf("Test succeeded.\n");
|
|
return EXIT_SUCCESS;
|
|
}
|