diff options
| author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-06-04 04:29:04 +0200 | 
|---|---|---|
| committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-06-04 04:29:04 +0200 | 
| commit | ad73b9440422c06805764da6058ebeb6d41a4f04 (patch) | |
| tree | e2f1c315c7b04d825347772e8a4180650e49ea3e /lib/sqfs | |
| parent | a07a965967f3ba44a74528f607d514502b928b17 (diff) | |
lzma compressor: add support for the "extreme" flag
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/sqfs')
| -rw-r--r-- | lib/sqfs/comp/compressor.c | 1 | ||||
| -rw-r--r-- | lib/sqfs/comp/lzma.c | 49 | 
2 files changed, 39 insertions, 11 deletions
diff --git a/lib/sqfs/comp/compressor.c b/lib/sqfs/comp/compressor.c index ea53339..2a0cebb 100644 --- a/lib/sqfs/comp/compressor.c +++ b/lib/sqfs/comp/compressor.c @@ -171,6 +171,7 @@ int sqfs_compressor_config_init(sqfs_compressor_config_t *cfg,  		cfg->opt.xz.pb = SQFS_XZ_DEFAULT_PB;  		break;  	case SQFS_COMP_LZMA: +		flag_mask |= SQFS_COMP_FLAG_LZMA_ALL;  		break;  	case SQFS_COMP_LZ4:  		flag_mask |= SQFS_COMP_FLAG_LZ4_ALL; diff --git a/lib/sqfs/comp/lzma.c b/lib/sqfs/comp/lzma.c index 2a6cd1f..8db018d 100644 --- a/lib/sqfs/comp/lzma.c +++ b/lib/sqfs/comp/lzma.c @@ -24,6 +24,7 @@  typedef struct {  	sqfs_compressor_t base;  	size_t block_size; +	sqfs_u32 flags;  } lzma_compressor_t;  static int lzma_write_options(sqfs_compressor_t *base, sqfs_file_t *file) @@ -39,18 +40,15 @@ static int lzma_read_options(sqfs_compressor_t *base, sqfs_file_t *file)  	return SQFS_ERROR_UNSUPPORTED;  } -static sqfs_s32 lzma_comp_block(sqfs_compressor_t *base, const sqfs_u8 *in, -				sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) +static sqfs_s32 try_compress(lzma_compressor_t *lzma, sqfs_u32 preset, +			     const sqfs_u8 *in, size_t size, +			     sqfs_u8 *out, size_t outsize)  { -	lzma_compressor_t *lzma = (lzma_compressor_t *)base;  	lzma_stream strm = LZMA_STREAM_INIT;  	lzma_options_lzma opt;  	int ret; -	if (outsize < LZMA_HEADER_SIZE || size >= 0x7FFFFFFF) -		return SQFS_ERROR_ARG_INVALID; - -	lzma_lzma_preset(&opt, LZMA_DEFAULT_LEVEL); +	lzma_lzma_preset(&opt, preset);  	opt.dict_size = lzma->block_size;  	if (lzma_alone_encoder(&strm, &opt) != LZMA_OK) { @@ -83,6 +81,33 @@ static sqfs_s32 lzma_comp_block(sqfs_compressor_t *base, const sqfs_u8 *in,  	return strm.total_out;  } +static sqfs_s32 lzma_comp_block(sqfs_compressor_t *base, const sqfs_u8 *in, +				sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) +{ +	lzma_compressor_t *lzma = (lzma_compressor_t *)base; +	sqfs_s32 ret, smallest; +	sqfs_u32 preset; + +	if (outsize < LZMA_HEADER_SIZE || size >= 0x7FFFFFFF) +		return SQFS_ERROR_ARG_INVALID; + +	preset = LZMA_DEFAULT_LEVEL; +	ret = try_compress(lzma, preset, in, size, out, outsize); +	if (ret < 0 || !(lzma->flags & SQFS_COMP_FLAG_LZMA_EXTREME)) +		return ret; + +	preset |= LZMA_PRESET_EXTREME; +	smallest = ret; + +	ret = try_compress(lzma, preset, in, size, out, outsize); +	if (ret < 0 || (ret > 0 && (smallest == 0 || ret < smallest))) +		return ret; + +	preset &= ~LZMA_PRESET_EXTREME; +	return smallest == 0 ? 0 : +		try_compress(lzma, preset, in, size, out, outsize); +} +  static sqfs_s32 lzma_uncomp_block(sqfs_compressor_t *base, const sqfs_u8 *in,  				  sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize)  { @@ -151,9 +176,7 @@ static void lzma_get_configuration(const sqfs_compressor_t *base,  	memset(cfg, 0, sizeof(*cfg));  	cfg->id = SQFS_COMP_LZMA;  	cfg->block_size = lzma->block_size; - -	if (base->do_block == lzma_uncomp_block) -		cfg->flags |= SQFS_COMP_FLAG_UNCOMPRESS; +	cfg->flags = lzma->flags;  }  static sqfs_object_t *lzma_create_copy(const sqfs_object_t *cmp) @@ -176,8 +199,11 @@ int lzma_compressor_create(const sqfs_compressor_config_t *cfg,  {  	sqfs_compressor_t *base;  	lzma_compressor_t *lzma; +	sqfs_u32 mask; + +	mask = SQFS_COMP_FLAG_GENERIC_ALL | SQFS_COMP_FLAG_LZMA_ALL; -	if (cfg->flags & ~SQFS_COMP_FLAG_GENERIC_ALL) +	if (cfg->flags & ~mask)  		return SQFS_ERROR_UNSUPPORTED;  	lzma = calloc(1, sizeof(*lzma)); @@ -186,6 +212,7 @@ int lzma_compressor_create(const sqfs_compressor_config_t *cfg,  		return SQFS_ERROR_ALLOC;  	lzma->block_size = cfg->block_size; +	lzma->flags = cfg->flags;  	if (lzma->block_size < SQFS_META_BLOCK_SIZE)  		lzma->block_size = SQFS_META_BLOCK_SIZE;  | 
