diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index e863078a481..a5ec9c1afc7 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -1780,6 +1780,7 @@ void _File::_bind_methods() { BIND_CONSTANT(COMPRESSION_FASTLZ); BIND_CONSTANT(COMPRESSION_DEFLATE); BIND_CONSTANT(COMPRESSION_ZSTD); + BIND_CONSTANT(COMPRESSION_GZIP); } _File::_File() { diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index f72f665d9e4..ec4fd3f476b 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -372,7 +372,8 @@ public: enum CompressionMode { COMPRESSION_FASTLZ = Compression::MODE_FASTLZ, COMPRESSION_DEFLATE = Compression::MODE_DEFLATE, - COMPRESSION_ZSTD = Compression::MODE_ZSTD + COMPRESSION_ZSTD = Compression::MODE_ZSTD, + COMPRESSION_GZIP = Compression::MODE_GZIP }; Error open_encrypted(const String &p_path, int p_mode_flags, const Vector &p_key); diff --git a/core/global_config.cpp b/core/global_config.cpp index caae73ee2e6..d8b88afd076 100644 --- a/core/global_config.cpp +++ b/core/global_config.cpp @@ -974,6 +974,8 @@ GlobalConfig::GlobalConfig() { custom_prop_info["compression/zstd/compression_level"] = PropertyInfo(Variant::INT, "compression/zstd/compression_level", PROPERTY_HINT_RANGE, "1,22,1"); GLOBAL_DEF("compression/zlib/compression_level", Z_DEFAULT_COMPRESSION); custom_prop_info["compression/zlib/compression_level"] = PropertyInfo(Variant::INT, "compression/zlib/compression_level", PROPERTY_HINT_RANGE, "-1,9,1"); + GLOBAL_DEF("compression/gzip/compression_level", Z_DEFAULT_COMPRESSION); + custom_prop_info["compression/gzip/compression_level"] = PropertyInfo(Variant::INT, "compression/gzip/compression_level", PROPERTY_HINT_RANGE, "-1,9,1"); using_datapack = false; } diff --git a/core/io/compression.cpp b/core/io/compression.cpp index f806c4da6dc..8c8f0b36552 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -52,23 +52,22 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, } } break; - case MODE_DEFLATE: { + case MODE_DEFLATE: + case MODE_GZIP: { + + int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16; z_stream strm; strm.zalloc = zipio_alloc; strm.zfree = zipio_free; strm.opaque = Z_NULL; - int level = GLOBAL_GET("compression/zlib/compression_level"); - int err = deflateInit(&strm, level); + int level = p_mode == MODE_DEFLATE ? GLOBAL_GET("compression/zlib/compression_level") : GLOBAL_GET("compression/gzip/compression_level"); + int err = deflateInit2(&strm, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY); if (err != Z_OK) return -1; strm.avail_in = p_src_size; int aout = deflateBound(&strm, p_src_size); - /*if (aout>p_src_size) { - deflateEnd(&strm); - return -1; - }*/ strm.avail_out = aout; strm.next_in = (Bytef *)p_src; strm.next_out = p_dst; @@ -100,13 +99,16 @@ int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) { return ss; } break; - case MODE_DEFLATE: { + case MODE_DEFLATE: + case MODE_GZIP: { + + int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16; z_stream strm; strm.zalloc = zipio_alloc; strm.zfree = zipio_free; strm.opaque = Z_NULL; - int err = deflateInit(&strm, Z_DEFAULT_COMPRESSION); + int err = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY); if (err != Z_OK) return -1; int aout = deflateBound(&strm, p_src_size); @@ -138,7 +140,10 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p } return ret_size; } break; - case MODE_DEFLATE: { + case MODE_DEFLATE: + case MODE_GZIP: { + + int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16; z_stream strm; strm.zalloc = zipio_alloc; @@ -146,7 +151,7 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p strm.opaque = Z_NULL; strm.avail_in = 0; strm.next_in = Z_NULL; - int err = inflateInit(&strm); + int err = inflateInit2(&strm, window_bits); ERR_FAIL_COND_V(err != Z_OK, -1); strm.avail_in = p_src_size; diff --git a/core/io/compression.h b/core/io/compression.h index 742f0f4d68a..bc39fc4185c 100644 --- a/core/io/compression.h +++ b/core/io/compression.h @@ -37,7 +37,8 @@ public: enum Mode { MODE_FASTLZ, MODE_DEFLATE, - MODE_ZSTD + MODE_ZSTD, + MODE_GZIP }; static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 6936a362e17..4a806aec6c5 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -516,7 +516,7 @@ struct _VariantCall { PoolByteArray compressed; Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]); - compressed.resize(Compression::get_max_compressed_buffer_size(ba->size())); + compressed.resize(Compression::get_max_compressed_buffer_size(ba->size(), mode)); int result = Compression::compress(compressed.write().ptr(), ba->read().ptr(), ba->size(), mode); result = result >= 0 ? result : 0;