mirror of
https://github.com/QB64-Phoenix-Edition/QB64pe.git
synced 2024-09-20 02:04:44 +00:00
Merge pull request #510 from a740g/compression-fixes
Improve func__deflate() & func__inflate()
This commit is contained in:
commit
de49e25475
3 changed files with 42 additions and 36 deletions
2
Makefile
2
Makefile
|
@ -324,8 +324,6 @@ else
|
|||
endif
|
||||
|
||||
ifneq ($(filter y,$(DEP_ZLIB)),)
|
||||
EXE_LIBS += $(MINIZ_OBJS) $(COMPRESSION_OBJS)
|
||||
|
||||
LICENSE_IN_USE += miniz
|
||||
endif
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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…
Reference in a new issue