static SquashStatus squash_wflz_decompress_buffer (SquashCodec* codec, size_t* decompressed_size, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_size)], size_t compressed_size, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_size)], SquashOptions* options) { const char* codec_name = squash_codec_get_name (codec); uint32_t decompressed_s; if (SQUASH_UNLIKELY(compressed_size < 12)) return squash_error (SQUASH_BUFFER_EMPTY); decompressed_s = wfLZ_GetDecompressedSize (compressed); #if SIZE_MAX < UINT32_MAX if (SQUASH_UNLIKELY(SIZE_MAX < decompressed_s)) return squash_error (SQUASH_RANGE); #endif if (SQUASH_UNLIKELY(decompressed_s == 0)) return squash_error (SQUASH_INVALID_BUFFER); if (SQUASH_UNLIKELY(decompressed_s > *decompressed_size)) return squash_error (SQUASH_BUFFER_FULL); if (codec_name[4] == '\0') { wfLZ_Decompress (compressed, decompressed); } else { uint8_t* dest = decompressed; uint32_t* chunk = NULL; uint8_t* compressed_block; while ( (compressed_block = wfLZ_ChunkDecompressLoop ((uint8_t*) compressed, &chunk)) != NULL ) { const uint32_t chunk_size = wfLZ_GetDecompressedSize (compressed_block); if (SQUASH_UNLIKELY((dest + chunk_size) > (decompressed + *decompressed_size))) return squash_error (SQUASH_BUFFER_FULL); wfLZ_Decompress (compressed_block, dest); dest += chunk_size; } } *decompressed_size = decompressed_s; return SQUASH_OK; }
//- static ERL_NIF_TERM nif_decompress(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] Get decompressed size. uint32_t decompressed_bytes = wfLZ_GetDecompressedSize((const uint8_t* const) input.data); if(!decompressed_bytes) { return(erlang_produce_error(env, "not_compressed")); } // [rad] Create binary stream to hold decompressed data. if(!enif_alloc_binary(decompressed_bytes, &bin)) { return(erlang_produce_error(env, "not_enough_memory")); } // [rad] Perform decompression. wfLZ_Decompress((const uint8_t* const) input.data, bin.data); return(enif_make_binary(env, &bin)); }
int64_t lzbench_wflz_decompress(char *inbuf, size_t insize, char *outbuf, size_t outsize, size_t, size_t, char*) { wfLZ_Decompress((const uint8_t*)inbuf, (uint8_t*)outbuf); return outsize; }
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; }