| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  compression.cpp                                                      */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2021-01-01 20:13:46 +01:00
										 |  |  | /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | #include "compression.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-07 19:33:38 -03:00
										 |  |  | #include "core/config/project_settings.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/io/zip_io.h"
 | 
					
						
							|  |  |  | #include "core/os/copymem.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-28 18:29:15 +02:00
										 |  |  | #include "thirdparty/misc/fastlz.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <zlib.h>
 | 
					
						
							| 
									
										
										
										
											2017-09-23 23:46:47 -04:00
										 |  |  | #include <zstd.h>
 | 
					
						
							| 
									
										
										
										
											2017-04-28 18:29:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode) { | 
					
						
							|  |  |  | 	switch (p_mode) { | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 		case MODE_FASTLZ: { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (p_src_size < 16) { | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 				uint8_t src[16]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				zeromem(&src[p_src_size], 16 - p_src_size); | 
					
						
							|  |  |  | 				copymem(src, p_src, p_src_size); | 
					
						
							|  |  |  | 				return fastlz_compress(src, 16, p_dst); | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				return fastlz_compress(p_src, p_src_size, p_dst); | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2017-07-13 14:41:10 -03:00
										 |  |  | 		case MODE_DEFLATE: | 
					
						
							|  |  |  | 		case MODE_GZIP: { | 
					
						
							|  |  |  | 			int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16; | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			z_stream strm; | 
					
						
							|  |  |  | 			strm.zalloc = zipio_alloc; | 
					
						
							|  |  |  | 			strm.zfree = zipio_free; | 
					
						
							|  |  |  | 			strm.opaque = Z_NULL; | 
					
						
							| 
									
										
										
										
											2017-07-17 21:05:38 -03:00
										 |  |  | 			int level = p_mode == MODE_DEFLATE ? zlib_level : gzip_level; | 
					
						
							| 
									
										
										
										
											2017-07-13 14:41:10 -03:00
										 |  |  | 			int err = deflateInit2(&strm, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (err != Z_OK) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				return -1; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			strm.avail_in = p_src_size; | 
					
						
							|  |  |  | 			int aout = deflateBound(&strm, p_src_size); | 
					
						
							|  |  |  | 			strm.avail_out = aout; | 
					
						
							|  |  |  | 			strm.next_in = (Bytef *)p_src; | 
					
						
							|  |  |  | 			strm.next_out = p_dst; | 
					
						
							|  |  |  | 			deflate(&strm, Z_FINISH); | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 			aout = aout - strm.avail_out; | 
					
						
							|  |  |  | 			deflateEnd(&strm); | 
					
						
							|  |  |  | 			return aout; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2017-06-08 20:43:56 -05:00
										 |  |  | 		case MODE_ZSTD: { | 
					
						
							| 
									
										
										
										
											2017-10-26 16:42:02 -04:00
										 |  |  | 			ZSTD_CCtx *cctx = ZSTD_createCCtx(); | 
					
						
							| 
									
										
										
										
											2019-01-03 22:30:03 -02:00
										 |  |  | 			ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, zstd_level); | 
					
						
							| 
									
										
										
										
											2017-10-26 16:42:02 -04:00
										 |  |  | 			if (zstd_long_distance_matching) { | 
					
						
							| 
									
										
										
										
											2019-01-03 22:30:03 -02:00
										 |  |  | 				ZSTD_CCtx_setParameter(cctx, ZSTD_c_enableLongDistanceMatching, 1); | 
					
						
							|  |  |  | 				ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, zstd_window_log_size); | 
					
						
							| 
									
										
										
										
											2017-10-26 16:42:02 -04:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-06-08 20:43:56 -05:00
										 |  |  | 			int max_dst_size = get_max_compressed_buffer_size(p_src_size, MODE_ZSTD); | 
					
						
							| 
									
										
										
										
											2017-10-26 16:42:02 -04:00
										 |  |  | 			int ret = ZSTD_compressCCtx(cctx, p_dst, max_dst_size, p_src, p_src_size, zstd_level); | 
					
						
							|  |  |  | 			ZSTD_freeCCtx(cctx); | 
					
						
							|  |  |  | 			return ret; | 
					
						
							| 
									
										
										
										
											2017-06-08 20:43:56 -05:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_V(-1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) { | 
					
						
							|  |  |  | 	switch (p_mode) { | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 		case MODE_FASTLZ: { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			int ss = p_src_size + p_src_size * 6 / 100; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (ss < 66) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				ss = 66; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 			return ss; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2017-07-13 14:41:10 -03:00
										 |  |  | 		case MODE_DEFLATE: | 
					
						
							|  |  |  | 		case MODE_GZIP: { | 
					
						
							|  |  |  | 			int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16; | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			z_stream strm; | 
					
						
							|  |  |  | 			strm.zalloc = zipio_alloc; | 
					
						
							|  |  |  | 			strm.zfree = zipio_free; | 
					
						
							|  |  |  | 			strm.opaque = Z_NULL; | 
					
						
							| 
									
										
										
										
											2017-07-13 14:41:10 -03:00
										 |  |  | 			int err = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (err != Z_OK) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				return -1; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			int aout = deflateBound(&strm, p_src_size); | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 			deflateEnd(&strm); | 
					
						
							|  |  |  | 			return aout; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2017-06-08 20:43:56 -05:00
										 |  |  | 		case MODE_ZSTD: { | 
					
						
							|  |  |  | 			return ZSTD_compressBound(p_src_size); | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_V(-1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode) { | 
					
						
							|  |  |  | 	switch (p_mode) { | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 		case MODE_FASTLZ: { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			int ret_size = 0; | 
					
						
							| 
									
										
										
										
											2016-08-22 01:14:08 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (p_dst_max_size < 16) { | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 				uint8_t dst[16]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				ret_size = fastlz_decompress(p_src, p_src_size, dst, 16); | 
					
						
							|  |  |  | 				copymem(p_dst, dst, p_dst_max_size); | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				ret_size = fastlz_decompress(p_src, p_src_size, p_dst, p_dst_max_size); | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-08-22 01:14:08 -03:00
										 |  |  | 			return ret_size; | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2017-07-13 14:41:10 -03:00
										 |  |  | 		case MODE_DEFLATE: | 
					
						
							|  |  |  | 		case MODE_GZIP: { | 
					
						
							|  |  |  | 			int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16; | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			z_stream strm; | 
					
						
							|  |  |  | 			strm.zalloc = zipio_alloc; | 
					
						
							|  |  |  | 			strm.zfree = zipio_free; | 
					
						
							|  |  |  | 			strm.opaque = Z_NULL; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			strm.avail_in = 0; | 
					
						
							|  |  |  | 			strm.next_in = Z_NULL; | 
					
						
							| 
									
										
										
										
											2017-07-13 14:41:10 -03:00
										 |  |  | 			int err = inflateInit2(&strm, window_bits); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			ERR_FAIL_COND_V(err != Z_OK, -1); | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			strm.avail_in = p_src_size; | 
					
						
							|  |  |  | 			strm.avail_out = p_dst_max_size; | 
					
						
							|  |  |  | 			strm.next_in = (Bytef *)p_src; | 
					
						
							|  |  |  | 			strm.next_out = p_dst; | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			err = inflate(&strm, Z_FINISH); | 
					
						
							| 
									
										
										
										
											2016-08-22 01:14:08 -03:00
										 |  |  | 			int total = strm.total_out; | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 			inflateEnd(&strm); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			ERR_FAIL_COND_V(err != Z_STREAM_END, -1); | 
					
						
							| 
									
										
										
										
											2016-08-22 01:14:08 -03:00
										 |  |  | 			return total; | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2017-06-08 20:43:56 -05:00
										 |  |  | 		case MODE_ZSTD: { | 
					
						
							| 
									
										
										
										
											2017-10-26 16:42:02 -04:00
										 |  |  | 			ZSTD_DCtx *dctx = ZSTD_createDCtx(); | 
					
						
							| 
									
										
										
										
											2019-04-18 13:17:34 +02:00
										 |  |  | 			if (zstd_long_distance_matching) { | 
					
						
							|  |  |  | 				ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, zstd_window_log_size); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-10-26 16:42:02 -04:00
										 |  |  | 			int ret = ZSTD_decompressDCtx(dctx, p_dst, p_dst_max_size, p_src, p_src_size); | 
					
						
							|  |  |  | 			ZSTD_freeDCtx(dctx); | 
					
						
							|  |  |  | 			return ret; | 
					
						
							| 
									
										
										
										
											2017-06-08 20:43:56 -05:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-22 01:14:08 -03:00
										 |  |  | 	ERR_FAIL_V(-1); | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-07-17 21:05:38 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-21 01:05:32 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  | 	This will handle both Gzip and Deflat streams. It will automatically allocate the output buffer into the provided p_dst_vect Vector. | 
					
						
							|  |  |  | 	This is required for compressed data who's final uncompressed size is unknown, as is the case for HTTP response bodies. | 
					
						
							|  |  |  | 	This is much slower however than using Compression::decompress because it may result in multiple full copies of the output buffer. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_size, const uint8_t *p_src, int p_src_size, Mode p_mode) { | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 	uint8_t *dst = nullptr; | 
					
						
							|  |  |  | 	int out_mark = 0; | 
					
						
							|  |  |  | 	z_stream strm; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(p_src_size <= 0, Z_DATA_ERROR); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// This function only supports GZip and Deflate
 | 
					
						
							|  |  |  | 	int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16; | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(p_mode != MODE_DEFLATE && p_mode != MODE_GZIP, Z_ERRNO); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Initialize the stream
 | 
					
						
							|  |  |  | 	strm.zalloc = Z_NULL; | 
					
						
							|  |  |  | 	strm.zfree = Z_NULL; | 
					
						
							|  |  |  | 	strm.opaque = Z_NULL; | 
					
						
							|  |  |  | 	strm.avail_in = 0; | 
					
						
							|  |  |  | 	strm.next_in = Z_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int err = inflateInit2(&strm, window_bits); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(err != Z_OK, -1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Setup the stream inputs
 | 
					
						
							|  |  |  | 	strm.next_in = (Bytef *)p_src; | 
					
						
							|  |  |  | 	strm.avail_in = p_src_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Ensure the destination buffer is empty
 | 
					
						
							|  |  |  | 	p_dst_vect->resize(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// decompress until deflate stream ends or end of file
 | 
					
						
							|  |  |  | 	do { | 
					
						
							|  |  |  | 		// Add another chunk size to the output buffer
 | 
					
						
							|  |  |  | 		// This forces a copy of the whole buffer
 | 
					
						
							|  |  |  | 		p_dst_vect->resize(p_dst_vect->size() + gzip_chunk); | 
					
						
							|  |  |  | 		// Get pointer to the actual output buffer
 | 
					
						
							|  |  |  | 		dst = p_dst_vect->ptrw(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Set the stream to the new output stream
 | 
					
						
							|  |  |  | 		// Since it was copied, we need to reset the stream to the new buffer
 | 
					
						
							|  |  |  | 		strm.next_out = &(dst[out_mark]); | 
					
						
							|  |  |  | 		strm.avail_out = gzip_chunk; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// run inflate() on input until output buffer is full and needs to be resized
 | 
					
						
							|  |  |  | 		// or input runs out
 | 
					
						
							|  |  |  | 		do { | 
					
						
							|  |  |  | 			ret = inflate(&strm, Z_SYNC_FLUSH); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			switch (ret) { | 
					
						
							|  |  |  | 				case Z_NEED_DICT: | 
					
						
							|  |  |  | 					ret = Z_DATA_ERROR; | 
					
						
							|  |  |  | 					[[fallthrough]]; | 
					
						
							|  |  |  | 				case Z_DATA_ERROR: | 
					
						
							|  |  |  | 				case Z_MEM_ERROR: | 
					
						
							|  |  |  | 				case Z_STREAM_ERROR: | 
					
						
							|  |  |  | 					WARN_PRINT(strm.msg); | 
					
						
							|  |  |  | 					(void)inflateEnd(&strm); | 
					
						
							|  |  |  | 					p_dst_vect->resize(0); | 
					
						
							|  |  |  | 					return ret; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} while (strm.avail_out > 0 && strm.avail_in > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		out_mark += gzip_chunk; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Encorce max output size
 | 
					
						
							|  |  |  | 		if (p_max_dst_size > -1 && strm.total_out > (uint64_t)p_max_dst_size) { | 
					
						
							|  |  |  | 			(void)inflateEnd(&strm); | 
					
						
							|  |  |  | 			p_dst_vect->resize(0); | 
					
						
							|  |  |  | 			return Z_BUF_ERROR; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} while (ret != Z_STREAM_END); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// If all done successfully, resize the output if it's larger than the actual output
 | 
					
						
							| 
									
										
										
										
											2020-12-08 20:58:49 +02:00
										 |  |  | 	if ((unsigned long)p_dst_vect->size() > strm.total_out) { | 
					
						
							| 
									
										
										
										
											2020-05-21 01:05:32 -07:00
										 |  |  | 		p_dst_vect->resize(strm.total_out); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// clean up and return
 | 
					
						
							|  |  |  | 	(void)inflateEnd(&strm); | 
					
						
							| 
									
										
										
										
											2020-12-08 20:58:49 +02:00
										 |  |  | 	return Z_OK; | 
					
						
							| 
									
										
										
										
											2020-05-21 01:05:32 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-17 21:05:38 -03:00
										 |  |  | int Compression::zlib_level = Z_DEFAULT_COMPRESSION; | 
					
						
							|  |  |  | int Compression::gzip_level = Z_DEFAULT_COMPRESSION; | 
					
						
							|  |  |  | int Compression::zstd_level = 3; | 
					
						
							| 
									
										
										
										
											2017-10-26 16:42:02 -04:00
										 |  |  | bool Compression::zstd_long_distance_matching = false; | 
					
						
							| 
									
										
										
										
											2019-04-18 13:17:34 +02:00
										 |  |  | int Compression::zstd_window_log_size = 27; // ZSTD_WINDOWLOG_LIMIT_DEFAULT
 | 
					
						
							| 
									
										
										
										
											2020-05-21 01:05:32 -07:00
										 |  |  | int Compression::gzip_chunk = 16384; |