Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve func__deflate() & func__inflate() #510

Merged
merged 2 commits into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,6 @@ else
endif

ifneq ($(filter y,$(DEP_ZLIB)),)
EXE_LIBS += $(MINIZ_OBJS) $(COMPRESSION_OBJS)

LICENSE_IN_USE += miniz
endif

Expand Down
9 changes: 8 additions & 1 deletion internal/c/parts/compression/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,11 @@ $(PATH_INTERNAL_C)/parts/compression/%.o: $(PATH_INTERNAL_C)/parts/compression/%
$(PATH_INTERNAL_C)/parts/compression/%.o: $(PATH_INTERNAL_C)/parts/compression/%.cpp
$(CXX) -O2 $(CXXFLAGS) -DDEPENDENCY_CONSOLE_ONLY -Wall $< -c -o $@

CLEAN_LIST += $(MINIZ_OBJS) $(COMPRESSION_OBJS)
COMPRESSION_LIB := $(PATH_INTERNAL_C)/parts/compression/compression.a

$(COMPRESSION_LIB): $(MINIZ_OBJS) $(COMPRESSION_OBJS)
$(AR) rcs $@ $(MINIZ_OBJS) $(COMPRESSION_OBJS)

EXE_LIBS += $(COMPRESSION_LIB)

CLEAN_LIST += $(COMPRESSION_LIB) $(MINIZ_OBJS) $(COMPRESSION_OBJS)
67 changes: 34 additions & 33 deletions internal/c/parts/compression/compression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,53 @@

#include "compression.h"
#include "qbs.h"

#include "miniz.h"

#include <vector>

uint32_t func__adler32(qbs *text) {
if (!text->len) return 1;
return (uint32_t) adler32(1, text->chr, text->len);
if (!text->len)
return 1;
return (uint32_t)adler32(1, text->chr, text->len);
}

uint32_t func__crc32(qbs *text) {
if (!text->len) return 0;
return (uint32_t) crc32(0, text->chr, text->len);
if (!text->len)
return 0;
return (uint32_t)crc32(0, text->chr, text->len);
}

qbs *func__deflate(qbs *text) {
uLongf filesize = (uint32_t)text->len; // length of the text
uLongf compsize = compressBound(filesize);
unsigned char *dest = (unsigned char *)malloc(compsize);
int32_t result = compress(dest, &compsize, text->chr, filesize);
qbs *ret = qbs_new(compsize, 1);
memcpy(ret->chr, dest, compsize);
free(dest);
return ret;
auto fileSize = uLongf(text->len);
auto compSize = compressBound(fileSize);
auto dest = qbs_new(compSize, 1); // compressing directly to the qbs gives us a performance boost
compress(dest->chr, &compSize, text->chr, fileSize); // discard result because we do not do any error checking
return qbs_left(dest, compSize);
}

qbs *func__inflate(qbs *text, int64_t originalsize, int32_t passed) {
int32_t result = 0;
if (passed == 1) {
uLongf uncompsize = originalsize;
unsigned char *dest = (unsigned char *)malloc(originalsize);
int32_t result = uncompress(dest, &uncompsize, text->chr, text->len);
qbs *ret = qbs_new(uncompsize, 1);
memcpy(ret->chr, dest, uncompsize);
free(dest);
return ret;
qbs *func__inflate(qbs *text, int64_t originalSize, int32_t passed) {
if (passed) {
// Passing negative values can do bad things to qbs
if (originalSize > 0) {
auto uncompSize = uLongf(originalSize);
auto dest = qbs_new(uncompSize, 1); // decompressing directly to the qbs gives us a performance boost
uncompress(dest->chr, &uncompSize, text->chr, uLongf(text->len)); // discard result because we do not do any error checking
return dest; // no size adjustment is done assuming the exact original size was passed
} else {
return qbs_new(0, 1); // simply return an empty qbs if originalSize is zero or negative
}
} else {
uLongf uncompsize = 0;
unsigned char *dest;
static const uLongf InflateChunkSize = 10 * 1024 * 1024;
std::vector<Byte> dest; // to get rid of malloc() and free()
auto compSize = uLongf(text->len);
uLongf uncompSize = 0;
do {
uncompsize = uncompsize + 10000000; // 10 mb original buffer, resized by 10 mb each pass until it's large enough to hold the uncompressed data.
dest = (unsigned char *)malloc(uncompsize);
result = uncompress(dest, &uncompsize, text->chr, text->len);
if (result == Z_BUF_ERROR)
free(dest); // if the buffer is too small, free the old buffer
} while (result == Z_BUF_ERROR); // and try again with a larger buffer
qbs *ret = qbs_new(uncompsize, 1);
memcpy(ret->chr, dest, uncompsize);
free(dest);
uncompSize += InflateChunkSize; // 10 mb original buffer, resized by 10 mb each pass until it's large enough to hold the uncompressed data.
dest.resize(uncompSize);
} while (uncompress(&dest[0], &uncompSize, text->chr, compSize) == Z_BUF_ERROR); // and try again with a larger buffer
auto ret = qbs_new(uncompSize, 1);
memcpy(ret->chr, &dest[0], uncompSize);
return ret;
}
}
Loading