aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Input/in_midi/CompressionUtility.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Input/in_midi/CompressionUtility.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-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.cpp270
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;
+}