Function LZNV_Decode_File_withBuffer
LZNV Tester CPP File Contents
Function LZNV Decode File with Buffer
LZNV_Decode_File_wBuffer is a sample function that performs file decompression with prior buffer manipulation
/// \brief LZNV_Decode_File_wBuffer performs a straight forward file compression with prior buffer manipulation.
/// \note The function performs internal buffering. If you do not want to perform your own buffering, please use LZNV_Decode_File.
/// \param[in] _encoding_method: One of the methods _LZNV_ULTRAFAST_COMPRESSION to _LZNV_BETTER_COMPRESSION or _LZNV_HUFFMAN_COMPRESSION to _LZNV_RLE64_COMPRESSION.
/// \param[in] _memory_level: The working size of the LZ algorithm. _LZNV_BUFFER_SIZE_256KB_INDX to _LZNV_BUFFER_SIZE_16MB_INDX.
/// \param[in] _wchr_filename_to_compress: Input file path to compress. Unicode WCHAR.
/// \param[in] _wchr_output_filename: Output file path to compress. Unicode WCHAR.
/// \return returns NO_ERROR (0) in case of no errors or one of the error codes defined in LZNV_Defines.h header file
/// possible values:
/// - _LZNV_ERROR_INVALID_COMPRESSION_METHOD
/// - _LZNV_ERROR_INVALID_BUFFER_SIZE
/// - _LZNV_ERROR_EXPORTED_MAIN_FUNC_NOT_FOUND
/// - _LZNV_ERROR_INVALID_PROCESS_SIZE
///
int32_t LZNV_Decode_File_wBuffer(const wchar_t* _wchr_filename_to_decompress, const wchar_t* _wchr_output_filename)
{
int32_t _res = 0;
ASSERT(_p_LZNV_DLL_Main_Buffer_funct);
if (!_p_LZNV_DLL_Main_Buffer_funct) {
wprintf(L"\n LZNV DLL Not Loaded? Aborting...\n\n");
return 1;
}
ASSERT(_wchr_output_filename);
ASSERT(_wchr_filename_to_decompress);
if ((!_wchr_filename_to_decompress) || (!_wchr_output_filename))
{
wprintf(L"\n LZNV DLL passed NULL parameters..\n\n");
return _LZNV_ERROR_INVALID_FILE_PATH_PARAMS;
}
FILE* fin = 0;
_wfopen_s(&fin, _wchr_filename_to_decompress, L"rb");
if (!fin) {
wprintf(L"\n Unable to open input file! Please check %s.\n\n", _wchr_filename_to_decompress);
return _LZNV_ERROR_INVALID_INPUT_FILE;
}
_wunlink(_wchr_output_filename);
FILE* fout = 0;
_wfopen_s(&fout, _wchr_output_filename, L"wb+");
if (!fout)
{
wprintf(L"\n Unable to open output file! Please check %s.\n\n", _wchr_filename_to_decompress);
if (fin)
fclose(fin);
return _LZNV_ERROR_INVALID_OUTPUT_FILE;
}
int64_t _file_len = (int64_t)_filelengthi64(_fileno(fin));
if (_file_len <= 0) {
wprintf(L"\n Invalid input file size! Please check %s.\n\n", _wchr_filename_to_decompress);
return _LZNV_ERROR_INVALID_INPUT_FILE_SIZE;
}
wprintf(L"\n Decompressing %s [ %lld bytes]", _wchr_filename_to_decompress, _file_len);
uint8_t _encoding_method = 0;
uint8_t _exe_compression = 0;
uint8_t _solid_compression = 0;
int32_t _chunk_size = 0;
if (NO_ERROR != ReadXZipHeader(fin, _encoding_method, _exe_compression, _solid_compression, _chunk_size))
{
wprintf(L"\n Read Header function failed! Please check %s.\n\n", _wchr_filename_to_decompress);
return _LZNV_ERROR_WRITING_HEADER;
}
ASSERT(((_encoding_method >= _LZNV_ULTRAFAST_COMPRESSION) && (_encoding_method < _LZNV_MAX_LZ_ALGORITHMS)) ||
((_encoding_method >= _LZNV_HUFFMAN_COMPRESSION) && (_encoding_method < _LZNV_MAX_ENTROPY_ALGORITHMS)));
if (!(((_encoding_method >= _LZNV_ULTRAFAST_COMPRESSION) && (_encoding_method < _LZNV_MAX_LZ_ALGORITHMS)) ||
((_encoding_method >= _LZNV_HUFFMAN_COMPRESSION) && (_encoding_method < _LZNV_MAX_ENTROPY_ALGORITHMS))))
{
return _LZNV_ERROR_INVALID_COMPRESSION_METHOD;
}
ASSERT(_chunk_size < ((64 << 20) + 1)); // 64MB Table Size MAX
if (_chunk_size > (64 << 20)) // 64MB Table Size MAX
{
return _LZNV_ERROR_BAD_HEADER_INFO_RECORDED; // bad header info on chunk size
}
uint8_t* _uint8_buffer_to_decode = (uint8_t*)malloc(_chunk_size + 4096 ); // _chunk_to_process + NO_BLOCKS * Buffer_Headers
uint8_t* _uint8_output_buffer = (uint8_t*)malloc(_chunk_size + 256); // _chunk_to_process + _santinel
ASSERT(_uint8_buffer_to_decode);
ASSERT(_uint8_output_buffer);
if (!_uint8_buffer_to_decode) {
wprintf(L"\n Not enough memory for chunk size %d... Exiting!\n\n", _chunk_size);
return _LZNV_ERROR_MEMORY_ALLOCATION_ERROR_OR_SIZE;
}
if (!_uint8_output_buffer) {
wprintf(L"\n Not enough memory for chunk size %d... Exiting!\n\n", _chunk_size);
return _LZNV_ERROR_MEMORY_ALLOCATION_ERROR_OR_SIZE;
}
int32_t _blockID = 0;
int64_t bufferSizeTotal = 0;
while (1)
{
int32_t toWrite = _getw(fin);
int32_t toRead = _getw(fin);
if (toWrite < 0 || toRead < 0) {
wprintf(L"\n\n Performing Exit.");
break;
}
#ifdef _DEBUG
wprintf(L"\n #%4d: To Read: %05d -> To Write: %05d", _blockID, toRead, toWrite);
#endif
ASSERT((toWrite > 0) && (toWrite <= _chunk_size));
if (!((toWrite > 0) && (toWrite <= _chunk_size)))
return 1201; // not enough output space
int32_t _write_bytes = toWrite;
int32_t _read_bytes = (int32_t)fread(_uint8_buffer_to_decode, 1, toRead, fin);
ASSERT(_read_bytes == toRead);
if(_read_bytes != toRead) {
return _LZNV_ERROR_INVALID_READ; // read error
}
bufferSizeTotal += _read_bytes;
//
// Prepare buffer decompression command structure
//
{
LZNV_BUFFER_COMMAND_PARAMS _lznv_buffer_decompression_commands = { 0 };
_lznv_buffer_decompression_commands._command_to_execute = _LZNV_COMMAND_DECODE; // Required
_lznv_buffer_decompression_commands._cpu_priority_level = _LZNV_NORMAL_PRIORITY_CLASS; // Optional
_lznv_buffer_decompression_commands._encoding_method = _encoding_method; // Required
_lznv_buffer_decompression_commands._p_source_buffer = _uint8_buffer_to_decode; // Required, Preallocate
_lznv_buffer_decompression_commands._i_source_buffer_size = _read_bytes; // Required, Non-zero value
_lznv_buffer_decompression_commands._p_destination_buffer = _uint8_output_buffer; // Required, Preallocate
_lznv_buffer_decompression_commands._i_destination_buffer_size = _write_bytes; // Required, Non-zero value
uint64_t dwS = GetTickCount64();
_res = (*_p_LZNV_DLL_Main_Buffer_funct)(_lznv_buffer_decompression_commands);
uint64_t dwE = GetTickCount64();
_write_bytes = _lznv_buffer_decompression_commands._i_destination_buffer_size;
wprintf(L"\n\n Decoding Block #%02d: %d --> %d [%lldms] [res = %d, %s]", _blockID, _read_bytes, _write_bytes, dwE - dwS, _res, _res == 0 ? L"Ok!" : L"NOk!");
if (NO_ERROR == _res)
{
fwrite(_uint8_output_buffer, 1, _write_bytes, fout);
}
else
{
break;
}
}
_blockID++;
}
if (_uint8_buffer_to_decode) {
free(_uint8_buffer_to_decode);
}
if (_uint8_output_buffer) {
free(_uint8_output_buffer);
}
if (fin) {
fclose(fin);
}
if (fout) {
fclose(fout);
}
return _res;
}