/* * 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 #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(); }