lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame^] | 1 | /* |
| 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
| 3 | * |
| 4 | * For licensing information, see the file 'LICENCE' in this directory. |
| 5 | * |
| 6 | * JFFS2 wrapper to the LZMA C SDK |
| 7 | * |
| 8 | */ |
| 9 | //#include <stdio.h> |
| 10 | //#include <stdlib.h> |
| 11 | //#include <linux/types.h> |
| 12 | //#include <sys/stat.h> |
| 13 | //#include <fcntl.h> |
| 14 | #include <linux/lzma.h> |
| 15 | |
| 16 | /* |
| 17 | 1.1. Header |
| 18 | |
| 19 | +------------+----+----+----+----+--+--+--+--+--+--+--+--+ |
| 20 | | Properties | Dictionary Size | Uncompressed Size | |
| 21 | +------------+----+----+----+----+--+--+--+--+--+--+--+--+ |
| 22 | |
| 23 | |
| 24 | 1.1.1. Properties |
| 25 | |
| 26 | The Properties field contains three properties. An abbreviation |
| 27 | is given in parentheses, followed by the value range of the |
| 28 | property. The field consists of |
| 29 | |
| 30 | 1) the number of literal context bits (lc, [0, 8]); |
| 31 | 2) the number of literal position bits (lp, [0, 4]); and |
| 32 | 3) the number of position bits (pb, [0, 4]). |
| 33 | |
| 34 | The properties are encoded using the following formula: |
| 35 | |
| 36 | Properties = (pb * 5 + lp) * 9 + lc |
| 37 | |
| 38 | The following C code illustrates a straightforward way to |
| 39 | decode the Properties field: |
| 40 | |
| 41 | uint8_t lc, lp, pb; |
| 42 | uint8_t prop = get_lzma_properties(); |
| 43 | if (prop > (4 * 5 + 4) * 9 + 8) |
| 44 | return LZMA_PROPERTIES_ERROR; |
| 45 | |
| 46 | pb = prop / (9 * 5); |
| 47 | prop -= pb * 9 * 5; |
| 48 | lp = prop / 9; |
| 49 | lc = prop - lp * 9; |
| 50 | */ |
| 51 | #if 0 |
| 52 | #define ZTE_LZMA_DICT //(0x100000) |
| 53 | #define ZTE_LZMA_LC //3 |
| 54 | #define ZTE_LZMA_LP //0 |
| 55 | #define ZTE_LZMA_PB //2 |
| 56 | #endif |
| 57 | |
| 58 | static CLzmaEncHandle *p_lzma; |
| 59 | static Byte propsEncoded_lzma[LZMA_PROPS_SIZE]; |
| 60 | static SizeT propsSize_lzma = sizeof(propsEncoded_lzma); |
| 61 | |
| 62 | static void lzma_free_workspace(void) |
| 63 | { |
| 64 | LzmaEnc_Destroy(p_lzma, &lzma_alloc, &lzma_alloc); |
| 65 | } |
| 66 | |
| 67 | static int INIT lzma_alloc_workspace(CLzmaEncProps * props) |
| 68 | { |
| 69 | if ((p_lzma = (CLzmaEncHandle *) LzmaEnc_Create(&lzma_alloc)) == NULL) { |
| 70 | PRINT_ERROR("Failed to allocate lzma deflate workspace\n"); |
| 71 | return -ENOMEM; |
| 72 | } |
| 73 | |
| 74 | if (LzmaEnc_SetProps(p_lzma, props) != SZ_OK) { |
| 75 | lzma_free_workspace(); |
| 76 | return -1; |
| 77 | } |
| 78 | |
| 79 | if (LzmaEnc_WriteProperties(p_lzma, propsEncoded_lzma, &propsSize_lzma) != SZ_OK) { |
| 80 | lzma_free_workspace(); |
| 81 | return -1; |
| 82 | } |
| 83 | |
| 84 | return 0; |
| 85 | } |
| 86 | |
| 87 | static int lzma_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t * sourcelen, uint32_t * dstlen) |
| 88 | { |
| 89 | SizeT compress_size = (SizeT) (*dstlen); |
| 90 | int ret; |
| 91 | |
| 92 | ret = LzmaEnc_MemEncode(p_lzma, cpage_out, &compress_size, data_in, *sourcelen, 0, NULL, &lzma_alloc, &lzma_alloc); |
| 93 | |
| 94 | if (ret != SZ_OK) |
| 95 | return -1; |
| 96 | |
| 97 | *dstlen = (uint32_t) compress_size; |
| 98 | |
| 99 | return 0; |
| 100 | } |
| 101 | |
| 102 | int lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen) |
| 103 | { |
| 104 | int ret; |
| 105 | SizeT dl = (SizeT) destlen; |
| 106 | SizeT sl = (SizeT) srclen; |
| 107 | ELzmaStatus status; |
| 108 | |
| 109 | ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded_lzma, propsSize_lzma, LZMA_FINISH_ANY, &status, &lzma_alloc); |
| 110 | |
| 111 | if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT) destlen) |
| 112 | { |
| 113 | return -1; |
| 114 | } |
| 115 | |
| 116 | return 0; |
| 117 | } |
| 118 | |
| 119 | int lzma_init(UInt32 *ztelzma_dict,int *ztelzma_lc,int *ztelzma_lp,int *ztelzma_pb) |
| 120 | { |
| 121 | int ret = -1; |
| 122 | CLzmaEncProps props; |
| 123 | LzmaEncProps_Init(&props); |
| 124 | |
| 125 | props.dictSize = LZMA_BEST_DICT(*ztelzma_dict); |
| 126 | props.level = LZMA_BEST_LEVEL; |
| 127 | props.lc = *ztelzma_lc; //ZTE_LZMA_LC; //LZMA_BEST_LC; |
| 128 | props.lp = *ztelzma_lp; //ZTE_LZMA_LP; //LZMA_BEST_LP; |
| 129 | props.pb = *ztelzma_pb; //ZTE_LZMA_PB; //LZMA_BEST_PB; |
| 130 | props.fb = LZMA_BEST_FB; |
| 131 | |
| 132 | ret = lzma_alloc_workspace(&props); |
| 133 | |
| 134 | return ret; |
| 135 | } |
| 136 | |
| 137 | #if 0 |
| 138 | int main(int argc, char *argv[]) |
| 139 | { |
| 140 | int ret = -1; |
| 141 | struct stat stat_buf; |
| 142 | char *file_name = NULL; |
| 143 | char out_file[2048] = { 0 }; |
| 144 | int fd1, fd2; |
| 145 | char *in; |
| 146 | uint32_t in_len; |
| 147 | char *out; |
| 148 | uint32_t out_len; |
| 149 | char *in2; |
| 150 | uint32_t in2_len; |
| 151 | int i, keep_flag = 0; |
| 152 | |
| 153 | /* |
| 154 | LZMA compressed file format |
| 155 | --------------------------- |
| 156 | Offset Size Description |
| 157 | 0 1 Special LZMA properties (lc,lp, pb in encoded form) |
| 158 | 1 4 Dictionary size (little endian) |
| 159 | 5 8 Uncompressed size (little endian). -1 means unknown size |
| 160 | 13 Compressed data |
| 161 | */ |
| 162 | uint8_t lzmainfo[13]; |
| 163 | uint32_t *p_dict = (uint32_t *)(&lzmainfo[1]); |
| 164 | uint64_t *p_uncompress_size = (uint64_t *)(&lzmainfo[5]); |
| 165 | |
| 166 | if (argc < 2) { |
| 167 | printf("usage:\n\t %s [-k] file\n", argv[0]); |
| 168 | return -1; |
| 169 | } |
| 170 | for (i = 1; i < argc; i++) { |
| 171 | if (strcmp(argv[i], "-k") == 0) |
| 172 | keep_flag = 1; |
| 173 | } |
| 174 | file_name = argv[argc - 1]; |
| 175 | ret = stat(file_name, &stat_buf); |
| 176 | if (ret < 0) { |
| 177 | printf("stat file %s failed\n", file_name); |
| 178 | return -1; |
| 179 | } |
| 180 | |
| 181 | in_len = stat_buf.st_size; |
| 182 | in = malloc(in_len); |
| 183 | in2 = malloc(in_len); |
| 184 | |
| 185 | fd1 = open(file_name, O_RDONLY, 0644); |
| 186 | if (fd1 < 0) { |
| 187 | perror("open file failed\n"); |
| 188 | return -1; |
| 189 | } |
| 190 | ret = read(fd1, in, in_len); |
| 191 | if (ret < 0) { |
| 192 | perror("read file failed\n"); |
| 193 | return -1; |
| 194 | } |
| 195 | close(fd1); |
| 196 | |
| 197 | sprintf(out_file, "%s.lzma", file_name); |
| 198 | //printf("out_file is %s\n",out_file); |
| 199 | fd2 = open(out_file, O_RDWR | O_CREAT | O_TRUNC, 0666); |
| 200 | if (fd2 < 0) { |
| 201 | perror("open out file failed\n"); |
| 202 | return -1; |
| 203 | } |
| 204 | |
| 205 | ret = lzma_init(); |
| 206 | if(ret < 0) { |
| 207 | printf("lzma_init failed\n"); |
| 208 | return -1; |
| 209 | } |
| 210 | |
| 211 | out = malloc(in_len * 2); |
| 212 | out_len = in_len * 2; |
| 213 | ret = lzma_compress(in, out, &in_len, &out_len); |
| 214 | if (ret < 0) { |
| 215 | printf("lzma compress fail\n"); |
| 216 | return -1; |
| 217 | } |
| 218 | |
| 219 | //(pb * 5 + lp) * 9 + lc; |
| 220 | lzmainfo[0] = (ZTE_LZMA_PB * 5 + ZTE_LZMA_LP) * 9 + ZTE_LZMA_LC; |
| 221 | *p_dict = ZTE_LZMA_DICT; |
| 222 | *p_uncompress_size = in_len; |
| 223 | ret = write(fd2, lzmainfo, sizeof(lzmainfo)); |
| 224 | if(ret < sizeof(lzmainfo)) { |
| 225 | printf("write failed:%d\n",ret ); |
| 226 | return -1; |
| 227 | } |
| 228 | |
| 229 | ret = write(fd2, out, out_len); |
| 230 | if(ret < out_len) { |
| 231 | printf("write failed:%d\n",ret ); |
| 232 | return -1; |
| 233 | } |
| 234 | close(fd2); |
| 235 | |
| 236 | ret = lzma_decompress(out, in2, out_len, in_len); |
| 237 | if (ret < 0) { |
| 238 | printf("lzma decompress fail\n"); |
| 239 | return -1; |
| 240 | } |
| 241 | |
| 242 | if (memcmp(in, in2, in_len) != 0) { |
| 243 | printf("in in2 not same\n"); |
| 244 | return -1; |
| 245 | } |
| 246 | |
| 247 | if (!keep_flag) |
| 248 | unlink(file_name); |
| 249 | return 0; |
| 250 | } |
| 251 | #endif |