static SquashStatus squash_wflz_compress_buffer (SquashCodec* codec, size_t* compressed_size, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_size)], size_t uncompressed_size, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_size)], SquashOptions* options) { const char* codec_name = squash_codec_get_name (codec); const uint32_t swap = ((uint32_t) squash_options_get_int_at (options, codec, SQUASH_WFLZ_OPT_ENDIANNESS) != SQUASH_WFLZ_HOST_ORDER); const int level = squash_options_get_int_at (options, codec, SQUASH_WFLZ_OPT_LEVEL); #if UINT32_MAX < SIZE_MAX if (SQUASH_UNLIKELY(UINT32_MAX < uncompressed_size)) return squash_error (SQUASH_RANGE); #endif if (*compressed_size < wfLZ_GetMaxCompressedSize ((uint32_t) uncompressed_size)) { return squash_error (SQUASH_BUFFER_FULL); } uint8_t* work_mem = (uint8_t*) malloc (wfLZ_GetWorkMemSize ()); uint32_t wres; if (codec_name[4] == '\0') { if (level == 1) { wres = wfLZ_CompressFast (uncompressed, (uint32_t) uncompressed_size, compressed, work_mem, swap); } else { wres = wfLZ_Compress (uncompressed, (uint32_t) uncompressed_size, compressed, work_mem, swap); } } else { wres = wfLZ_ChunkCompress ((uint8_t*) uncompressed, (uint32_t) uncompressed_size, squash_options_get_size_at (options, codec, SQUASH_WFLZ_OPT_CHUNK_SIZE), compressed, work_mem, swap, level == 1 ? 1 : 0); } #if SIZE_MAX < UINT32_MAX if (SQUASH_UNLIKELY(SIZE_MAX < wres)) { free (work_mem); return squash_error (SQUASH_RANGE); } #endif *compressed_size = (size_t) wres; free (work_mem); return SQUASH_LIKELY(*compressed_size > 0) ? SQUASH_OK : squash_error (SQUASH_FAILED); }
//-- static ERL_NIF_TERM nif_compress(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary input; if(!enif_inspect_iolist_as_binary(env, argv[0], &input)) { return(enif_make_badarg(env)); } ErlNifBinary bin; // [rad] Figure out maximum compression buffer size. uint32_t compressed_bytes = wfLZ_GetMaxCompressedSize(input.size); // [rad] Get size of recommended scratchpad. uint32_t scratchpad_bytes = wfLZ_GetWorkMemSize(); if(!enif_alloc_binary(compressed_bytes, &bin)) { return(erlang_produce_error(env, "not_enough_memory")); } // [rad] Allocate scratchpad buffer. uint8_t* scratchpad = malloc(scratchpad_bytes); // [rad] Perform compression. uint32_t data_comp_size = wfLZ_Compress((const uint8_t* const) input.data, input.size, (uint8_t* const) bin.data, (const uint8_t*) scratchpad, 0); // [rad] We no longer need scratchpad. free(scratchpad); if(!data_comp_size) { return(erlang_produce_error(env, "compression_error")); } if(!enif_realloc_binary(&bin, data_comp_size)) { return(erlang_produce_error(env, "not_enough_memory")); } return(enif_make_binary(env, &bin)); }
static size_t squash_wflz_get_max_compressed_size (SquashCodec* codec, size_t uncompressed_size) { const char* codec_name = squash_codec_get_name (codec); #if UINT32_MAX < SIZE_MAX if (SQUASH_UNLIKELY(UINT32_MAX < uncompressed_size)) return (squash_error (SQUASH_RANGE), 0); #endif const uint32_t res = codec_name[4] == '\0' ? wfLZ_GetMaxCompressedSize ((uint32_t) uncompressed_size) : wfLZ_GetMaxChunkCompressedSize ((uint32_t) uncompressed_size, SQUASH_WFLZ_MIN_CHUNK_SIZE); #if SIZE_MAX < UINT32_MAX if (SQUASH_UNLIKELY(SIZE_MAX < res)) return (squash_error (SQUASH_RANGE)); #endif return res; }
int main( int argc, char** argv ) { const char* in; uint32_t hashCheck = 1; uint64_t hashValue, hashValue2; uint32_t compressedSize, uncompressedSize; uint8_t* uncompressed; uint8_t* workMem; uint8_t* compressed; if( argc < 2 ) { printf( "Usage: wflz input_file" ); return 0; } in = argv[1]; printf( "\nwfLZ[%s]\n", in ); { FILE* fh = fopen( in, "rb" ); if( fh == NULL ) { printf( "Error: Could not read input file '%s'.\n", in ); return 0; } fseek( fh, 0, SEEK_END ); uncompressedSize = (uint32_t)ftell( fh ); uncompressed = (uint8_t*)Malloc( uncompressedSize ); if( uncompressed == NULL ) { fclose( fh ); printf( "Error: Allocation failed.\n" ); return 0; } fseek( fh, 0, SEEK_SET ); if( fread( uncompressed, 1, uncompressedSize, fh ) != uncompressedSize ) { fclose( fh ); printf( "Error: File read failed.\n" ); return 0; } fclose( fh ); } workMem = (uint8_t*)Malloc( wfLZ_GetWorkMemSize() ); if( workMem == NULL ) { printf( "Error: Allocation failed.\n" ); return 0; } compressed = (uint8_t*)Malloc( wfLZ_GetMaxCompressedSize( uncompressedSize ) ); hashValue = hashCheck ? HashData( uncompressed, uncompressedSize ) : 0 ; //#define CAPTURING_PROFILE #ifdef CAPTURING_PROFILE { uint32_t i; for( i = 0; i != 10000; ++i ) { #endif compressedSize = wfLZ_CompressFast( uncompressed, uncompressedSize, compressed, workMem, 0 ); if( hashCheck ) { memset( uncompressed, 0, uncompressedSize ); } wfLZ_Decompress( compressed, uncompressed ); #ifdef CAPTURING_PROFILE } } #endif free( workMem ); free( compressed ); hashValue2 = hashCheck ? HashData( uncompressed, uncompressedSize ) : 0 ; free( uncompressed ); printf( "Compression Ratio: %.2f\n", ((float)compressedSize)/((float)uncompressedSize) ); if( hashCheck && hashValue != hashValue2 ) { printf( "Error: Hash check mismatch!\n" ); return -1; } return 0; }