| /* | 
 |  * JFFS2 -- Journalling Flash File System, Version 2. | 
 |  * | 
 |  * For licensing information, see the file 'LICENCE' in this directory. | 
 |  * | 
 |  * JFFS2 wrapper to the LZMA C SDK | 
 |  * | 
 |  */ | 
 |  | 
 | #include <linux/lzma.h> | 
 | #include "compr.h" | 
 |  | 
 | #ifdef __KERNEL__ | 
 | 	static DEFINE_MUTEX(deflate_mutex); | 
 | #endif | 
 |  | 
 | CLzmaEncHandle *p; | 
 | Byte propsEncoded[LZMA_PROPS_SIZE]; | 
 | SizeT propsSize = sizeof(propsEncoded); | 
 |  | 
 | STATIC void lzma_free_workspace(void) | 
 | { | 
 | 	LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc); | 
 | } | 
 |  | 
 | STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props) | 
 | { | 
 | 	if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL) | 
 | 	{ | 
 | 		PRINT_ERROR("Failed to allocate lzma deflate workspace\n"); | 
 | 		return -ENOMEM; | 
 | 	} | 
 |  | 
 | 	if (LzmaEnc_SetProps(p, props) != SZ_OK) | 
 | 	{ | 
 | 		lzma_free_workspace(); | 
 | 		return -1; | 
 | 	} | 
 | 	 | 
 | 	if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK) | 
 | 	{ | 
 | 		lzma_free_workspace(); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 |         return 0; | 
 | } | 
 |  | 
 | STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out, | 
 | 			      uint32_t *sourcelen, uint32_t *dstlen) | 
 | { | 
 | 	SizeT compress_size = (SizeT)(*dstlen); | 
 | 	int ret; | 
 |  | 
 | 	#ifdef __KERNEL__ | 
 | 		mutex_lock(&deflate_mutex); | 
 | 	#endif | 
 |  | 
 | 	ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen, | 
 | 		0, NULL, &lzma_alloc, &lzma_alloc); | 
 |  | 
 | 	#ifdef __KERNEL__ | 
 | 		mutex_unlock(&deflate_mutex); | 
 | 	#endif | 
 |  | 
 | 	if (ret != SZ_OK) | 
 | 		return -1; | 
 |  | 
 | 	*dstlen = (uint32_t)compress_size; | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, | 
 | 				 uint32_t srclen, uint32_t destlen) | 
 | { | 
 | 	int ret; | 
 | 	SizeT dl = (SizeT)destlen; | 
 | 	SizeT sl = (SizeT)srclen; | 
 | 	ELzmaStatus status; | 
 | 	 | 
 | 	ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded, | 
 | 		propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc); | 
 |  | 
 | 	if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen) | 
 | 		return -1; | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | static struct jffs2_compressor jffs2_lzma_comp = { | 
 | 	.priority = JFFS2_LZMA_PRIORITY, | 
 | 	.name = "lzma", | 
 | 	.compr = JFFS2_COMPR_LZMA, | 
 | 	.compress = &jffs2_lzma_compress, | 
 | 	.decompress = &jffs2_lzma_decompress, | 
 | 	.disabled = 0, | 
 | }; | 
 |  | 
 | int INIT jffs2_lzma_init(void) | 
 | { | 
 |         int ret; | 
 | 	CLzmaEncProps props; | 
 | 	LzmaEncProps_Init(&props); | 
 |  | 
 |         props.dictSize = LZMA_BEST_DICT(0x2000); | 
 |         props.level = LZMA_BEST_LEVEL; | 
 |         props.lc = LZMA_BEST_LC; | 
 |         props.lp = LZMA_BEST_LP; | 
 |         props.pb = LZMA_BEST_PB; | 
 |         props.fb = LZMA_BEST_FB; | 
 |  | 
 | 	ret = lzma_alloc_workspace(&props); | 
 |         if (ret < 0) | 
 |                 return ret; | 
 |  | 
 | 	ret = jffs2_register_compressor(&jffs2_lzma_comp); | 
 | 	if (ret) | 
 | 		lzma_free_workspace(); | 
 | 	 | 
 |         return ret; | 
 | } | 
 |  | 
 | void jffs2_lzma_exit(void) | 
 | { | 
 | 	jffs2_unregister_compressor(&jffs2_lzma_comp); | 
 | 	lzma_free_workspace(); | 
 | } |