| /* | 
 |  * 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 <stdio.h> | 
 | //#include <stdlib.h> | 
 | //#include <linux/types.h> | 
 | //#include <sys/stat.h> | 
 | //#include <fcntl.h> | 
 | #include <linux/lzma.h> | 
 |  | 
 | /* | 
 | 1.1. Header | 
 |  | 
 |         +------------+----+----+----+----+--+--+--+--+--+--+--+--+ | 
 |         | Properties |  Dictionary Size  |   Uncompressed Size   | | 
 |         +------------+----+----+----+----+--+--+--+--+--+--+--+--+ | 
 |  | 
 |  | 
 | 1.1.1. Properties | 
 |  | 
 |         The Properties field contains three properties. An abbreviation | 
 |         is given in parentheses, followed by the value range of the | 
 |         property. The field consists of | 
 |  | 
 |             1) the number of literal context bits (lc, [0, 8]); | 
 |             2) the number of literal position bits (lp, [0, 4]); and | 
 |             3) the number of position bits (pb, [0, 4]). | 
 |  | 
 |         The properties are encoded using the following formula: | 
 |  | 
 |             Properties = (pb * 5 + lp) * 9 + lc | 
 |  | 
 |         The following C code illustrates a straightforward way to | 
 |         decode the Properties field: | 
 |  | 
 |             uint8_t lc, lp, pb; | 
 |             uint8_t prop = get_lzma_properties(); | 
 |             if (prop > (4 * 5 + 4) * 9 + 8) | 
 |                 return LZMA_PROPERTIES_ERROR; | 
 |  | 
 |             pb = prop / (9 * 5); | 
 |             prop -= pb * 9 * 5; | 
 |             lp = prop / 9; | 
 |             lc = prop - lp * 9; | 
 | */ | 
 | #if 0 | 
 | #define ZTE_LZMA_DICT   //(0x100000) | 
 | #define ZTE_LZMA_LC     //3 | 
 | #define ZTE_LZMA_LP     //0 | 
 | #define ZTE_LZMA_PB     //2 | 
 | #endif | 
 |  | 
 | static CLzmaEncHandle *p_lzma; | 
 | static Byte propsEncoded_lzma[LZMA_PROPS_SIZE]; | 
 | static SizeT propsSize_lzma = sizeof(propsEncoded_lzma); | 
 |  | 
 | static void lzma_free_workspace(void) | 
 | { | 
 | 	LzmaEnc_Destroy(p_lzma, &lzma_alloc, &lzma_alloc); | 
 | } | 
 |  | 
 | static int INIT lzma_alloc_workspace(CLzmaEncProps * props) | 
 | { | 
 | 	if ((p_lzma = (CLzmaEncHandle *) LzmaEnc_Create(&lzma_alloc)) == NULL) { | 
 | 		PRINT_ERROR("Failed to allocate lzma deflate workspace\n"); | 
 | 		return -ENOMEM; | 
 | 	} | 
 |  | 
 | 	if (LzmaEnc_SetProps(p_lzma, props) != SZ_OK) { | 
 | 		lzma_free_workspace(); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	if (LzmaEnc_WriteProperties(p_lzma, propsEncoded_lzma, &propsSize_lzma) != SZ_OK) { | 
 | 		lzma_free_workspace(); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | static int lzma_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t * sourcelen, uint32_t * dstlen) | 
 | { | 
 | 	SizeT compress_size = (SizeT) (*dstlen); | 
 | 	int ret; | 
 |  | 
 | 	ret = LzmaEnc_MemEncode(p_lzma, cpage_out, &compress_size, data_in, *sourcelen, 0, NULL, &lzma_alloc, &lzma_alloc); | 
 |  | 
 | 	if (ret != SZ_OK) | 
 | 		return -1; | 
 |  | 
 | 	*dstlen = (uint32_t) compress_size; | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | int 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_lzma, propsSize_lzma, LZMA_FINISH_ANY, &status, &lzma_alloc); | 
 |  | 
 | 	if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT) destlen) | 
 | 		{ | 
 | 			return -1; | 
 | 		} | 
 | 	 | 
 | 	return 0; | 
 | } | 
 |  | 
 | int lzma_init(UInt32 *ztelzma_dict,int *ztelzma_lc,int *ztelzma_lp,int *ztelzma_pb) | 
 | { | 
 | 	int ret = -1; | 
 | 	CLzmaEncProps props; | 
 | 	LzmaEncProps_Init(&props); | 
 |  | 
 | 	props.dictSize = LZMA_BEST_DICT(*ztelzma_dict); | 
 | 	props.level = LZMA_BEST_LEVEL; | 
 | 	props.lc = *ztelzma_lc;           //ZTE_LZMA_LC;	    //LZMA_BEST_LC; | 
 | 	props.lp = *ztelzma_lp;           //ZTE_LZMA_LP;		//LZMA_BEST_LP; | 
 | 	props.pb = *ztelzma_pb;           //ZTE_LZMA_PB;		//LZMA_BEST_PB; | 
 | 	props.fb = LZMA_BEST_FB; | 
 | 	 | 
 | 	ret = lzma_alloc_workspace(&props); | 
 |  | 
 | 	return ret; | 
 | } | 
 |  | 
 | #if 0 | 
 | int main(int argc, char *argv[]) | 
 | { | 
 | 	int ret = -1; | 
 | 	struct stat stat_buf; | 
 | 	char *file_name = NULL; | 
 | 	char out_file[2048] = { 0 }; | 
 | 	int fd1, fd2; | 
 | 	char *in; | 
 | 	uint32_t in_len; | 
 | 	char *out; | 
 | 	uint32_t out_len; | 
 | 	char *in2; | 
 | 	uint32_t in2_len; | 
 | 	int i, keep_flag = 0; | 
 |  | 
 | 	/* | 
 | 	LZMA compressed file format | 
 | --------------------------- | 
 | Offset Size Description | 
 |   0     1   Special LZMA properties (lc,lp, pb in encoded form) | 
 |   1     4   Dictionary size (little endian) | 
 |   5     8   Uncompressed size (little endian). -1 means unknown size | 
 |  13         Compressed data | 
 |  */ | 
 | 	uint8_t lzmainfo[13]; | 
 | 	uint32_t *p_dict = (uint32_t *)(&lzmainfo[1]); | 
 | 	uint64_t *p_uncompress_size = (uint64_t *)(&lzmainfo[5]); | 
 |  | 
 | 	if (argc < 2) { | 
 | 		printf("usage:\n\t %s [-k] file\n", argv[0]); | 
 | 		return -1; | 
 | 	} | 
 | 	for (i = 1; i < argc; i++) { | 
 | 		if (strcmp(argv[i], "-k") == 0) | 
 | 			keep_flag = 1; | 
 | 	} | 
 | 	file_name = argv[argc - 1]; | 
 | 	ret = stat(file_name, &stat_buf); | 
 | 	if (ret < 0) { | 
 | 		printf("stat file %s failed\n", file_name); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	in_len = stat_buf.st_size; | 
 | 	in = malloc(in_len); | 
 | 	in2 = malloc(in_len); | 
 |  | 
 | 	fd1 = open(file_name, O_RDONLY, 0644); | 
 | 	if (fd1 < 0) { | 
 | 		perror("open file failed\n"); | 
 | 		return -1; | 
 | 	} | 
 | 	ret = read(fd1, in, in_len); | 
 | 	if (ret < 0) { | 
 | 		perror("read file failed\n"); | 
 | 		return -1; | 
 | 	} | 
 | 	close(fd1); | 
 |  | 
 | 	sprintf(out_file, "%s.lzma", file_name); | 
 | 	//printf("out_file is %s\n",out_file); | 
 | 	fd2 = open(out_file, O_RDWR | O_CREAT | O_TRUNC, 0666); | 
 | 	if (fd2 < 0) { | 
 | 		perror("open out file failed\n"); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	ret = lzma_init(); | 
 | 	if(ret < 0) { | 
 | 		printf("lzma_init failed\n"); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	out = malloc(in_len * 2); | 
 | 	out_len = in_len * 2; | 
 | 	ret = lzma_compress(in, out, &in_len, &out_len); | 
 | 	if (ret < 0) { | 
 | 		printf("lzma compress fail\n"); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	//(pb * 5 + lp) * 9 + lc; | 
 | 	lzmainfo[0] = (ZTE_LZMA_PB * 5 + ZTE_LZMA_LP) * 9 + ZTE_LZMA_LC; | 
 | 	*p_dict = ZTE_LZMA_DICT; | 
 | 	*p_uncompress_size = in_len; | 
 | 	ret = write(fd2, lzmainfo, sizeof(lzmainfo)); | 
 | 	if(ret < sizeof(lzmainfo)) { | 
 | 		printf("write failed:%d\n",ret ); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	ret = write(fd2, out, out_len); | 
 | 	if(ret < out_len) { | 
 | 		printf("write failed:%d\n",ret ); | 
 | 		return -1; | 
 | 	} | 
 | 	close(fd2); | 
 |  | 
 | 	ret = lzma_decompress(out, in2, out_len, in_len); | 
 | 	if (ret < 0) { | 
 | 		printf("lzma decompress fail\n"); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	if (memcmp(in, in2, in_len) != 0) { | 
 | 		printf("in in2 not same\n"); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	if (!keep_flag) | 
 | 		unlink(file_name); | 
 | 	return 0; | 
 | } | 
 | #endif |