GF_Err gf_gz_compress_payload_ex(u8 **data, u32 data_len, u32 *max_size, u8 data_offset, Bool skip_if_larger, u8 **out_comp_data)
{
	z_stream stream;
	int err;
	char *dest = (char *)gf_malloc(sizeof(char)*data_len*ZLIB_COMPRESS_SAFE);
	stream.next_in = (Bytef*)(*data) + data_offset;
	stream.avail_in = (uInt)data_len - data_offset;
	stream.next_out = ( Bytef*)dest;
	stream.avail_out = (uInt)data_len*ZLIB_COMPRESS_SAFE;
	stream.zalloc = (alloc_func)NULL;
	stream.zfree = (free_func)NULL;
	stream.opaque = (voidpf)NULL;

	err = deflateInit2(&stream, 9, Z_DEFLATED, 16+MAX_WBITS, 8, Z_DEFAULT_STRATEGY);

	if (err != Z_OK) {
		gf_free(dest);
		return GF_IO_ERR;
	}

	err = deflate(&stream, Z_FINISH);
	if (err != Z_STREAM_END) {
		deflateEnd(&stream);
		gf_free(dest);
		return GF_IO_ERR;
	}
	if (data_len-data_offset < stream.total_out) {
		if (skip_if_larger) {
			gf_free(dest);
			deflateEnd(&stream);
			*max_size = (u32) stream.total_out;
			return GF_OK;
		}
		GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[GZ] compressed data (%d) larger than input (%d)\n", (u32) stream.total_out, (u32) data_len ));
	}

	if (out_comp_data) {
		data = out_comp_data;
	}

	if (*max_size < stream.total_out) {
		*max_size = data_len*ZLIB_COMPRESS_SAFE;
		*data = (char*)gf_realloc(*data, *max_size * sizeof(char));
	}

	memcpy((*data) , dest, sizeof(char)*stream.total_out);
	*max_size = (u32) stream.total_out;
	gf_free(dest);

	deflateEnd(&stream);
	return GF_OK;
}
GF_Err gf_gz_compress_payload_ex(u8 **data, u32 data_len, u32 *max_size, u8 data_offset, Bool skip_if_larger, u8 **out_comp_data)
{
	z_stream stream;
	int err;
	char *dest = (char *)gf_malloc(sizeof(char)*data_len*ZLIB_COMPRESS_SAFE);
	stream.next_in = (Bytef*)(*data) + data_offset;
	stream.avail_in = (uInt)data_len - data_offset;
	stream.next_out = ( Bytef*)dest;
	stream.avail_out = (uInt)data_len*ZLIB_COMPRESS_SAFE;
	stream.zalloc = (alloc_func)NULL;
	stream.zfree = (free_func)NULL;
	stream.opaque = (voidpf)NULL;

	err = deflateInit2(&stream, 9, Z_DEFLATED, 16+MAX_WBITS, 8, Z_DEFAULT_STRATEGY);

	if (err != Z_OK) {
		gf_free(dest);
		return GF_IO_ERR;
	}

	err = deflate(&stream, Z_FINISH);
	if (err != Z_STREAM_END) {
		deflateEnd(&stream);
		gf_free(dest);
		return GF_IO_ERR;
	}
	if (data_len-data_offset < stream.total_out) {
		if (skip_if_larger) {
			gf_free(dest);
			deflateEnd(&stream);
			*max_size = (u32) stream.total_out;
			return GF_OK;
		}
		GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[GZ] compressed data (%d) larger than input (%d)\n", (u32) stream.total_out, (u32) data_len ));
	}

	if (out_comp_data) {
		data = out_comp_data;
	}

	if (*max_size < stream.total_out) {
		*max_size = data_len*ZLIB_COMPRESS_SAFE;
		*data = (char*)gf_realloc(*data, *max_size * sizeof(char));
	}

	memcpy((*data) , dest, sizeof(char)*stream.total_out);
	*max_size = (u32) stream.total_out;
	gf_free(dest);

	deflateEnd(&stream);
	return GF_OK;
}