// CompressSimpleHelper //------------------------------------------------------------------------------ void TestCompressor::CompressSimpleHelper( const char * data, size_t size, size_t expectedCompressedSize, bool shouldCompress ) const { // raw input strings may not be aligned on Linux/OSX, so copy // them to achieve our required alignment char * alignedData = FNEW( char[ size ] ); memcpy( alignedData, data, size ); data = alignedData; // compress Compressor c; const bool compressed = c.Compress( data, size ); TEST_ASSERT( compressed == shouldCompress ); const size_t compressedSize = c.GetResultSize(); if ( expectedCompressedSize > 0 ) { TEST_ASSERT( compressedSize == expectedCompressedSize ); } void const * compressedMem = c.GetResult(); // decompress Compressor d; d.Decompress( compressedMem ); const size_t decompressedSize = d.GetResultSize(); TEST_ASSERT( decompressedSize == size ); TEST_ASSERT( memcmp( data, d.GetResult(), size ) == 0 ); FDELETE_ARRAY( alignedData ); }
int main(int argc, char*argv[]) { if (argc < 2) { return 1; } bool unpack = strstr(argv[1], ".pack") != nullptr; FILE* fptr = fopen(argv[1], "rb"); if (!fptr) { printf("Could not open %s\n", argv[1]); return 1; } fseek(fptr, 0, SEEK_END); u32 size = ftell(fptr); fseek(fptr, 0, SEEK_SET); int os = 0; CompressionParameters params; memset(¶ms, 0, sizeof(params)); if (unpack) { fread(&os, 4, 1, fptr); fread(¶ms.contextCount, 1, 1, fptr); fread(params.weights, params.contextCount, 1, fptr); fread(params.contexts, params.contextCount, 1, fptr); size -= ftell(fptr); } u8* data = (u8*)malloc(size + 10); memset(data, 0, size + 10); data += 10; // Ugly, but we can ensure we have a few zero bytes at the beginning of the input. fread(data, 1, size, fptr); fclose(fptr); char ofn[256]; strcpy(ofn, argv[1]); if (unpack) { *strrchr(ofn, '.') = 0; strcat(ofn, ".unpack"); } else { strcat(ofn, ".pack"); } u8* out = (u8*)malloc(65536); memset(out, 0, 65536); out += 10; // Ugly, but we can ensure we have a few zero bytes at the beginning of the output. FILE* ofptr = fopen(ofn, "wb"); if (!ofptr) { printf("Could not open %s\n", argv[1]); return 1; } if (unpack) { Compressor* comp = new Compressor(); comp->Decompress(¶ms, &data[size - 4], out, os); fwrite(out, os, 1, ofptr); } else { Compressor* comp = new Compressor(); os = 65528; comp->Compress(¶ms, data, size, out, &os); Invert(out, os); fwrite(&size, 4, 1, ofptr); fwrite(¶ms.contextCount, 1, 1, ofptr); fwrite(params.weights, params.contextCount, 1, ofptr); fwrite(params.contexts, params.contextCount, 1, ofptr); fwrite(out, os, 1, ofptr); } fclose(ofptr); return 0; }
// CompressHelper //------------------------------------------------------------------------------ void TestCompressor::CompressHelper( const char * fileName ) const { // read some test data into a file AutoPtr< void > data; size_t dataSize; { FileStream fs; TEST_ASSERT( fs.Open( fileName ) ); dataSize = (size_t)fs.GetFileSize(); data = (char *)ALLOC( dataSize ); TEST_ASSERT( (uint32_t)fs.Read( data.Get(), dataSize ) == dataSize ); } OUTPUT( "File : %s\n", fileName ); OUTPUT( "Size : %u\n", (uint32_t)dataSize ); // compress the data to obtain size Compressor comp; comp.Compress( data.Get(), dataSize ); size_t compressedSize = comp.GetResultSize(); AutoPtr< char > compressedData( (char *)ALLOC( compressedSize ) ); memcpy( compressedData.Get(), comp.GetResult(), compressedSize ); float compressedPerc = ( (float)compressedSize / (float)dataSize ) * 100.0f; OUTPUT( "Compressed Size: %u (%2.1f%% of original)\n", (uint32_t)compressedSize, compressedPerc ); // decompress to check we get original data back Compressor decomp; decomp.Decompress( compressedData.Get() ); size_t uncompressedSize = decomp.GetResultSize(); TEST_ASSERT( uncompressedSize == dataSize ); for ( size_t i=0; i<uncompressedSize; ++i ) { TEST_ASSERT( ( (char *)data.Get() )[ i ] == ( (char *)decomp.GetResult() )[ i ] ); } // speed checks //-------------- const size_t NUM_REPEATS( 100 ); // compress the data several times to get more stable throughput value Timer t; for ( size_t i=0; i<NUM_REPEATS; ++i ) { Compressor c; c.Compress( data.Get(), dataSize ); TEST_ASSERT( c.GetResultSize() == compressedSize ); } float compressTimeTaken = t.GetElapsed(); double compressThroughputMBs = ( ( (double)dataSize / 1024.0 * (double)NUM_REPEATS ) / compressTimeTaken ) / 1024.0; OUTPUT( " Comp Speed: %2.1f MB/s - %2.3fs (%u repeats)\n", (float)compressThroughputMBs, compressTimeTaken, NUM_REPEATS ); // decompress the data Timer t2; for ( size_t i=0; i<NUM_REPEATS; ++i ) { Compressor d; d.Decompress( compressedData.Get() ); TEST_ASSERT( d.GetResultSize() == dataSize ); } float decompressTimeTaken = t2.GetElapsed(); double decompressThroughputMBs = ( ( (double)dataSize / 1024.0 * (double)NUM_REPEATS ) / decompressTimeTaken ) / 1024.0; OUTPUT( " Decomp Speed: %2.1f MB/s - %2.3fs (%u repeats)\n", (float)decompressThroughputMBs, decompressTimeTaken, NUM_REPEATS ); // time memcpy to compare with Timer t0; for ( size_t i=0; i<NUM_REPEATS; ++i ) { char * mem = (char *)ALLOC( dataSize ); memcpy( mem, data.Get(), dataSize ); FREE( mem ); } float memcpyTimeTaken = t0.GetElapsed(); double memcpyThroughputMBs = ( ( (double)dataSize / 1024.0 * (double)NUM_REPEATS ) / memcpyTimeTaken ) / 1024.0; OUTPUT( " MemCpy Speed: %2.1f MB/s - %2.3fs (%u repeats)\n", (float)memcpyThroughputMBs, memcpyTimeTaken, NUM_REPEATS ); }