diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Input/in_midi/CompressionUtility.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Input/in_midi/CompressionUtility.cpp')
-rw-r--r-- | Src/Plugins/Input/in_midi/CompressionUtility.cpp | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_midi/CompressionUtility.cpp b/Src/Plugins/Input/in_midi/CompressionUtility.cpp new file mode 100644 index 00000000..2da502d3 --- /dev/null +++ b/Src/Plugins/Input/in_midi/CompressionUtility.cpp @@ -0,0 +1,270 @@ +#include "CompressionUtility.h" +#include "malloc.h" +#include <cstring> +#include "zlib.h" +#include "minizip/unzip.h" + + +#define dir_delimter '/' +#define MAX_FILENAME 512 +#define READ_SIZE 8192 + +/// <summary> +/// Compress given buffer as GZIP. +/// Dont forget to free out buffer!!!! +/// </summary> +/// <param name="input"></param> +/// <param name="input_size"></param> +/// <param name="ppvOut"></param> +/// <param name="out_size"></param> +/// <returns></returns> +int CompressionUtility::CompressAsGZip(const void* input, size_t input_size, void** ppvOut, size_t& out_size) +{ + z_stream zlib_stream; + zlib_stream.next_in = (Bytef*)input; + zlib_stream.avail_in = (uInt)input_size; + zlib_stream.next_out = Z_NULL; + zlib_stream.avail_out = Z_NULL; + zlib_stream.zalloc = (alloc_func)0; + zlib_stream.zfree = (free_func)0; + zlib_stream.opaque = 0; + int ret = deflateInit2(&zlib_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16 + MAX_WBITS), 8, Z_DEFAULT_STRATEGY); + + unsigned full_length = 2000; + unsigned half_length = input_size / 2; + + unsigned compLength = full_length; + unsigned char* comp = (unsigned char*)malloc(compLength); + + bool done = false; + + while (!done) + { + if (zlib_stream.total_out >= compLength) + { + // Increase size of output buffer + unsigned char* uncomp2 = (unsigned char*)malloc(compLength + half_length); + memcpy(uncomp2, comp, compLength); + compLength += half_length; + free(comp); + comp = uncomp2; + } + + zlib_stream.next_out = (Bytef*)(comp + zlib_stream.total_out); + zlib_stream.avail_out = compLength - zlib_stream.total_out; + + // Deflate another chunk. + ret = deflate(&zlib_stream, Z_FINISH); + if (Z_STREAM_END == ret) + { + done = true; + } + else if (Z_OK != ret) + { + break; + } + } + if (Z_OK != deflateEnd(&zlib_stream)) + { + free(comp); + return ret; + } + + *ppvOut = (void*)comp; + out_size = zlib_stream.total_out; + + return ret; +} +/// <summary> +/// Decompress given buffer. +/// Dont forget to free out buffer!!!! +/// </summary> +/// <param name="input"></param> +/// <param name="input_size"></param> +/// <param name="ppvOut"></param> +/// <param name="out_size"></param> +/// <returns></returns> +int CompressionUtility::DecompressGZip(const void* input, size_t input_size, void** ppvOut, size_t& out_size) +{ + z_stream zlib_stream; + zlib_stream.next_in = (Bytef*)input; + zlib_stream.avail_in = (uInt)input_size; + zlib_stream.next_out = Z_NULL; + zlib_stream.avail_out = Z_NULL; + zlib_stream.zalloc = (alloc_func)0; + zlib_stream.zfree = (free_func)0; + zlib_stream.opaque = Z_NULL; + + int ret = inflateInit2(&zlib_stream, (16 + MAX_WBITS)); + if (Z_OK != ret) + { + return ret; + } + unsigned full_length = input_size; + unsigned half_length = input_size / 2; + + unsigned uncompLength = full_length; + unsigned char* uncomp = (unsigned char*)malloc(uncompLength); + + bool done = false; + + while (!done) + { + if (zlib_stream.total_out >= uncompLength) + { + // Increase size of output buffer + unsigned char* uncomp2 = (unsigned char*)malloc(uncompLength + half_length); + memcpy(uncomp2, uncomp, uncompLength); + uncompLength += half_length; + free(uncomp); + uncomp = uncomp2; + } + + zlib_stream.next_out = (Bytef*)(uncomp + zlib_stream.total_out); + zlib_stream.avail_out = uncompLength - zlib_stream.total_out; + + // Inflate another chunk. + ret = inflate(&zlib_stream, Z_SYNC_FLUSH); + if (Z_STREAM_END == ret) + { + done = true; + } + else if (Z_OK != ret) + { + break; + } + } + if (Z_OK != inflateEnd(&zlib_stream)) + { + free(uncomp); + return ret; + } + + *ppvOut = (void*)uncomp; + out_size = zlib_stream.total_out; + return ret; +} + +/// <summary> +/// Returns inflated first file inside the ZIP container, +/// rest are ignored!!!!! +/// </summary> +/// <param name="input"></param> +/// <param name="input_size"></param> +/// <param name="ppvOut"></param> +/// <param name="out_size"></param> +/// <returns></returns> +int CompressionUtility::DecompressPKZip(const char* fn, void** ppvOut, size_t& out_size) +{ + // Open the zip file + unzFile zipfile = unzOpen(fn); + if (nullptr == zipfile) + { + // file not found + return -1; + } + + // Get info about the zip file + unz_global_info global_info; + if (UNZ_OK != unzGetGlobalInfo(zipfile, &global_info)) + { + // could not read file global info + unzClose(zipfile); + return -1; + } + + // Buffer to hold data read from the zip file. + //char read_buffer[READ_SIZE]; + + // Loop to extract all files + for (uLong i = 0; i < global_info.number_entry; ++i) + { + // Get info about current file. + unz_file_info file_info; + char filename[MAX_FILENAME]; + if (unzGetCurrentFileInfo( + zipfile, + &file_info, + filename, + MAX_FILENAME, + NULL, 0, NULL, 0) != UNZ_OK) + { + // could not read file info + unzClose(zipfile); + return -1; + } + + // Check if this entry is a directory or file. + const size_t filename_length = strlen(filename); + if (filename[filename_length - 1] == dir_delimter) + { + // Entry is a directory, skip it + } + else + { + // Entry is a file, so extract it. + if (unzOpenCurrentFile(zipfile) != UNZ_OK) + { + // could not open file + unzClose(zipfile); + return -1; + } + + unsigned full_length = READ_SIZE * 2; + unsigned half_length = READ_SIZE; + + unsigned uncompLength = full_length; + unsigned char* uncomp = (unsigned char*)malloc(uncompLength); + + size_t total_out = 0; + int error = UNZ_OK; + do + { + if (total_out >= uncompLength) + { + // Increase size of output buffer + unsigned char* uncomp2 = (unsigned char*)malloc(uncompLength + half_length); + memcpy(uncomp2, uncomp, uncompLength); + uncompLength += half_length; + free(uncomp); + uncomp = uncomp2; + } + + error = unzReadCurrentFile(zipfile, uncomp + total_out, uncompLength - total_out); + if (error < 0) + { + // something happened + unzCloseCurrentFile(zipfile); + unzClose(zipfile); + return -1; + } + + // Write data to buffer. + if (error > 0) + { + total_out += error; + } + } while (error > 0); + + *ppvOut = (void*)uncomp; + out_size = total_out; + } + + unzCloseCurrentFile(zipfile); + + // Go the the next entry listed in the zip file. + //if ((i + 1) < global_info.number_entry) + //{ + // if (unzGoToNextFile(zipfile) != UNZ_OK) + // { + // printf("cound not read next file\n"); + // unzClose(zipfile); + // return -1; + // } + //} + } + + unzClose(zipfile); + + return UNZ_OK; +} |