From 345746d34d9f64aa41a87608626da2209fc69f56 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sun, 14 Nov 2021 18:01:37 -0800 Subject: [PATCH] zlib interface --- BeefLibs/Beefy2D/src/utils/Compression.bf | 57 ++++++++++ BeefySysLib/util/Compress.cpp | 126 ++++++++++++++++++++++ BeefySysLib/util/Compress.h | 16 +++ 3 files changed, 199 insertions(+) create mode 100644 BeefLibs/Beefy2D/src/utils/Compression.bf create mode 100644 BeefySysLib/util/Compress.cpp create mode 100644 BeefySysLib/util/Compress.h diff --git a/BeefLibs/Beefy2D/src/utils/Compression.bf b/BeefLibs/Beefy2D/src/utils/Compression.bf new file mode 100644 index 00000000..a680b9ea --- /dev/null +++ b/BeefLibs/Beefy2D/src/utils/Compression.bf @@ -0,0 +1,57 @@ +using System; +using System.Collections; + +namespace utils +{ + class Compression + { + [CallingConvention(.Stdcall), CLink] + extern static Span Compression_Compress(void* ptr, int size); + + [CallingConvention(.Stdcall), CLink] + extern static Span Compression_Decompress(void* ptr, int size); + + [CallingConvention(.Stdcall), CLink] + extern static void Compression_Free(void* ptr); + + public static Result Compress(Span inData, List outData) + { + var outSpan = Compression_Compress(inData.Ptr, inData.Length); + if ((outSpan.Length == 0) && (inData.Length != 0)) + return .Err; + outData.AddRange(outSpan); + Compression_Free(outSpan.Ptr); + return .Ok; + } + + public static Result Compress(Span inData, String outData) + { + var outSpan = Compression_Compress(inData.Ptr, inData.Length); + if ((outSpan.Length == 0) && (inData.Length != 0)) + return .Err; + outData.Insert(outData.Length, StringView((.)outSpan.Ptr, outSpan.Length)); + Compression_Free(outSpan.Ptr); + return .Ok; + } + + public static Result Decompress(Span inData, List outData) + { + var outSpan = Compression_Decompress(inData.Ptr, inData.Length); + if ((outSpan.Length == 0) && (inData.Length != 0)) + return .Err; + outData.AddRange(outSpan); + Compression_Free(outSpan.Ptr); + return .Ok; + } + + public static Result Decompress(Span inData, String outData) + { + var outSpan = Compression_Decompress(inData.Ptr, inData.Length); + if ((outSpan.Length == 0) && (inData.Length != 0)) + return .Err; + outData.Insert(outData.Length, StringView((.)outSpan.Ptr, outSpan.Length)); + Compression_Free(outSpan.Ptr); + return .Ok; + } + } +} diff --git a/BeefySysLib/util/Compress.cpp b/BeefySysLib/util/Compress.cpp new file mode 100644 index 00000000..7040a226 --- /dev/null +++ b/BeefySysLib/util/Compress.cpp @@ -0,0 +1,126 @@ +#include "Compress.h" +#include "third_party/zlib/zlib.h" +#include "TLSingleton.h" + +#pragma warning(disable:4190) + +USING_NS_BF; + +bool Compression::Compress(Span inData, Array& outData) +{ + outData.Reserve(128); + + z_stream zs; + zs.zalloc = Z_NULL; + zs.zfree = Z_NULL; + zs.opaque = Z_NULL; + zs.avail_in = (int)inData.mSize; + zs.next_in = inData.mVals; + zs.next_out = outData.mVals; + zs.avail_out = outData.mAllocSize; + + deflateInit(&zs, Z_BEST_COMPRESSION); + + bool isDone = false; + bool hadError = false; + + while (true) + { + bool isDone = zs.avail_in == 0; + + int err = deflate(&zs, isDone ? Z_FINISH : Z_NO_FLUSH); + outData.mSize = (int)(zs.next_out - outData.mVals); + + if (err < 0) + { + hadError = true; + break; + } + + if ((isDone) && (err == Z_STREAM_END)) + break; + + if (zs.avail_out == 0) + { + outData.Reserve((int)outData.mAllocSize + (int)outData.mAllocSize / 2 + 1); + zs.next_out = outData.mVals + outData.mSize; + zs.avail_out = outData.mAllocSize - outData.mSize; + } + } + + deflateEnd(&zs); + return !hadError; +} + +bool Compression::Decompress(Span inData, Array& outData) +{ + outData.Reserve(128); + + z_stream zs; + zs.zalloc = Z_NULL; + zs.zfree = Z_NULL; + zs.opaque = Z_NULL; + zs.avail_in = (int)inData.mSize; + zs.next_in = inData.mVals; + zs.next_out = outData.mVals; + zs.avail_out = outData.mAllocSize; + + inflateInit(&zs, Z_BEST_COMPRESSION); + + bool isDone = false; + bool hadError = false; + + while (true) + { + bool isDone = zs.avail_in == 0; + + int err = inflate(&zs, isDone ? Z_FINISH : Z_NO_FLUSH); + outData.mSize = (int)(zs.next_out - outData.mVals); + + if (err < 0) + { + hadError = true; + break; + } + + if ((isDone) && (err == Z_STREAM_END)) + break; + + if (zs.avail_out == 0) + { + outData.Reserve((int)outData.mAllocSize + (int)outData.mAllocSize / 2 + 1); + zs.next_out = outData.mVals + outData.mSize; + zs.avail_out = outData.mAllocSize - outData.mSize; + } + } + + inflateEnd(&zs); + return !hadError; +} + +////////////////////////////////////////////////////////////////////////// + +BF_EXPORT Span BF_CALLTYPE Compression_Compress(void* ptr, int size) +{ + Array outData; + if (!Compression::Compress(Span((uint8*)ptr, size), outData)) + return Span(); + uint8* outPtr = outData.mVals; + outData.mVals = NULL; + return Span(outPtr, outData.mSize); +} + +BF_EXPORT Span BF_CALLTYPE Compression_Decompress(void* ptr, int size) +{ + Array outData; + if (!Compression::Decompress(Span((uint8*)ptr, size), outData)) + return Span(); + uint8* outPtr = outData.mVals; + outData.mVals = NULL; + return Span(outPtr, outData.mSize); +} + +BF_EXPORT void BF_CALLTYPE Compression_Free(void* ptr) +{ + delete ptr; +} diff --git a/BeefySysLib/util/Compress.h b/BeefySysLib/util/Compress.h new file mode 100644 index 00000000..06785abb --- /dev/null +++ b/BeefySysLib/util/Compress.h @@ -0,0 +1,16 @@ +#pragma once + +#include "../Common.h" +#include "Array.h" +#include "Span.h" + +NS_BF_BEGIN; + +class Compression +{ +public: + static bool Compress(Span inData, Array& outData); + static bool Decompress(Span inData, Array& outData); +}; + +NS_BF_END;