wok-6.x rev 18757
syslinux: compress c32 modules
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Tue Dec 29 08:59:31 2015 +0100 (2015-12-29) |
parents | 88d6c3ec605b |
children | 924e6ea5da10 |
files | syslinux/receipt syslinux/stuff/extra/loadhigh.u |
line diff
1.1 --- a/syslinux/receipt Mon Dec 28 20:47:30 2015 +0000 1.2 +++ b/syslinux/receipt Tue Dec 29 08:59:31 2015 +0100 1.3 @@ -20,6 +20,7 @@ 1.4 compile_rules() 1.5 { 1.6 rm -f $src/core/isolinux.bin 1.7 + patch -p 0 < $stuff/extra/loadhigh.u 1.8 patch -p 0 < $stuff/extra/iso9660.u 1.9 patch -p 0 < $stuff/extra/readconfig.u 1.10 #patch -p 0 < $stuff/extra/fs.u 1.11 @@ -51,8 +52,8 @@ 1.12 { 1.13 mkdir -p $fs/boot/isolinux 1.14 cp -a $src/core/isolinux.bin $fs/boot/isolinux 1.15 - cp -a $src/com32/modules/md5sum.c32 $fs/boot/isolinux/c32box.c32 1.16 - cp -a $src/com32/menu/vesamenu.c32 $fs/boot/isolinux 1.17 + lzma e $src/com32/modules/md5sum.c32 $fs/boot/isolinux/c32box.c32 1.18 + lzma e $src/com32/menu/vesamenu.c32 $fs/boot/isolinux/vesamenu.c32 1.19 # $stuff/isolinux.msg is the old way the have a splash image. 1.20 cp $stuff/*.cfg $stuff/*.txt $stuff/help.* $stuff/opts.* $fs/boot/isolinux 1.21 rm -f $fs/boot/isolinux/common.cfg $fs/boot/isolinux/default.cfg
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/syslinux/stuff/extra/loadhigh.u Tue Dec 29 08:59:31 2015 +0100 2.3 @@ -0,0 +1,554 @@ 2.4 +--- core/fs/loadhigh.c 2.5 ++++ core/fs/loadhigh.c 2.6 +@@ -36,6 +36,11 @@ 2.7 + #include <minmax.h> 2.8 + #include "core.h" 2.9 + #include "fs.h" 2.10 ++#define LZLOAD ".c32 modules can be compressed with lz4 or lzma" 2.11 ++#ifdef LZLOAD 2.12 ++#include "../unlz4.c" 2.13 ++#include "../unlzma.c" 2.14 ++#endif 2.15 + 2.16 + #define MAX_CHUNK (1 << 20) /* 1 MB */ 2.17 + 2.18 +@@ -51,6 +56,10 @@ 2.19 + uint32_t sector_mask; 2.20 + size_t pad; 2.21 + uint32_t retflags = 0; 2.22 ++#ifdef LZLOAD 2.23 ++ char *unpacked = (char *) regs->edi.l; 2.24 ++ size_t unpackedsz; 2.25 ++#endif 2.26 + 2.27 + bytes = regs->eax.l; 2.28 + zero_mask = regs->edx.w[0]; 2.29 +@@ -101,6 +110,27 @@ 2.30 + break; 2.31 + } 2.32 + } 2.33 ++ 2.34 ++#ifdef LZLOAD 2.35 ++ unpackedsz = buf - unpacked; 2.36 ++ switch (* (short *) unpacked) { 2.37 ++ char *packed; 2.38 ++ case 0x005D: 2.39 ++ packed = unpacked + * (unsigned long *) (unpacked + 5) 2.40 ++ - unpackedsz + 1024; 2.41 ++ 2.42 ++ if (packed < unpacked + 1024) 2.43 ++ packed = unpacked + 1024; 2.44 ++ memmove(packed, unpacked, unpackedsz); 2.45 ++ unlzma(packed, unpacked, packed + unpackedsz /* head */); 2.46 ++ buf = packed; 2.47 ++ break; 2.48 ++ case 0x2204: 2.49 ++ case 0x2102: 2.50 ++ buf = unlz4(unpacked, buf); 2.51 ++ break; 2.52 ++ } 2.53 ++#endif 2.54 + 2.55 + pad = (size_t)buf & zero_mask; 2.56 + if (pad) 2.57 +--- /dev/null 2.58 ++++ core/unlzma.c 2.59 +@@ -0,0 +1,383 @@ 2.60 ++typedef unsigned char uint8_t; 2.61 ++typedef unsigned short uint16_t; 2.62 ++typedef unsigned uint32_t; 2.63 ++typedef unsigned long long uint64_t; 2.64 ++typedef unsigned size_t; 2.65 ++#define SWAP_LE32(x) (x) 2.66 ++#define SWAP_LE64(x) (x) 2.67 ++/* vi: set sw=4 ts=4: */ 2.68 ++/* 2.69 ++ * Small lzma deflate implementation. 2.70 ++ * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> 2.71 ++ * 2.72 ++ * Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/) 2.73 ++ * Copyright (C) 1999-2005 Igor Pavlov 2.74 ++ * 2.75 ++ * Licensed under GPLv2 or later, see file LICENSE in this source tree. 2.76 ++ */ 2.77 ++ 2.78 ++#define PACKED __attribute__ ((packed)) 2.79 ++#define ALWAYS_INLINE inline 2.80 ++#define speed_inline 2.81 ++#define size_inline ALWAYS_INLINE 2.82 ++ 2.83 ++ 2.84 ++typedef struct { 2.85 ++ uint8_t *ptr; 2.86 ++ 2.87 ++ uint32_t code; 2.88 ++ uint32_t range; 2.89 ++ uint32_t bound; 2.90 ++} rc_t; 2.91 ++ 2.92 ++#define RC_TOP_BITS 24 2.93 ++#define RC_MOVE_BITS 5 2.94 ++#define RC_MODEL_TOTAL_BITS 11 2.95 ++ 2.96 ++/* Called twice, but one callsite is in speed_inline'd rc_is_bit_1() */ 2.97 ++static void rc_do_normalize(rc_t *rc) 2.98 ++{ 2.99 ++ rc->range <<= 8; 2.100 ++ rc->code = (rc->code << 8) | *rc->ptr++; 2.101 ++} 2.102 ++ 2.103 ++static ALWAYS_INLINE void rc_normalize(rc_t *rc) 2.104 ++{ 2.105 ++ if (rc->range < (1 << RC_TOP_BITS)) { 2.106 ++ rc_do_normalize(rc); 2.107 ++ } 2.108 ++} 2.109 ++ 2.110 ++/* Called once */ 2.111 ++static void rc_init(rc_t *rc) /*, int buffer_size) */ 2.112 ++{ 2.113 ++ int i; 2.114 ++ 2.115 ++ rc->range = 0; 2.116 ++ for (i = 0; i < 5; i++) { 2.117 ++ rc_do_normalize(rc); 2.118 ++ } 2.119 ++ rc->range = 0xffffffff; 2.120 ++} 2.121 ++ 2.122 ++/* rc_is_bit_1 is called 9 times */ 2.123 ++static speed_inline int rc_is_bit_1(rc_t *rc, uint16_t *p) 2.124 ++{ 2.125 ++ rc_normalize(rc); 2.126 ++ rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS); 2.127 ++ if (rc->code < rc->bound) { 2.128 ++ rc->range = rc->bound; 2.129 ++ *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS; 2.130 ++ return 0; 2.131 ++ } 2.132 ++ rc->range -= rc->bound; 2.133 ++ rc->code -= rc->bound; 2.134 ++ *p -= *p >> RC_MOVE_BITS; 2.135 ++ return 1; 2.136 ++} 2.137 ++ 2.138 ++/* Called 4 times in unlzma loop */ 2.139 ++static ALWAYS_INLINE int rc_get_bit(rc_t *rc, uint16_t *p, int *symbol) 2.140 ++{ 2.141 ++ int ret = rc_is_bit_1(rc, p); 2.142 ++ *symbol = *symbol * 2 + ret; 2.143 ++ return ret; 2.144 ++} 2.145 ++ 2.146 ++/* Called once */ 2.147 ++static ALWAYS_INLINE int rc_direct_bit(rc_t *rc) 2.148 ++{ 2.149 ++ rc_normalize(rc); 2.150 ++ rc->range >>= 1; 2.151 ++ if (rc->code >= rc->range) { 2.152 ++ rc->code -= rc->range; 2.153 ++ return 1; 2.154 ++ } 2.155 ++ return 0; 2.156 ++} 2.157 ++ 2.158 ++/* Called twice */ 2.159 ++static speed_inline void 2.160 ++rc_bit_tree_decode(rc_t *rc, uint16_t *p, int num_levels, int *symbol) 2.161 ++{ 2.162 ++ int i = num_levels; 2.163 ++ 2.164 ++ *symbol = 1; 2.165 ++ while (i--) 2.166 ++ rc_get_bit(rc, p + *symbol, symbol); 2.167 ++ *symbol -= 1 << num_levels; 2.168 ++} 2.169 ++ 2.170 ++ 2.171 ++typedef struct { 2.172 ++ uint8_t pos; 2.173 ++ uint32_t dict_size; 2.174 ++ uint64_t dst_size; 2.175 ++} PACKED lzma_header_t; 2.176 ++ 2.177 ++ 2.178 ++/* #defines will force compiler to compute/optimize each one with each usage. 2.179 ++ * Have heart and use enum instead. */ 2.180 ++enum { 2.181 ++ LZMA_BASE_SIZE = 1846, 2.182 ++ LZMA_LIT_SIZE = 768, 2.183 ++ 2.184 ++ LZMA_NUM_POS_BITS_MAX = 4, 2.185 ++ 2.186 ++ LZMA_LEN_NUM_LOW_BITS = 3, 2.187 ++ LZMA_LEN_NUM_MID_BITS = 3, 2.188 ++ LZMA_LEN_NUM_HIGH_BITS = 8, 2.189 ++ 2.190 ++ LZMA_LEN_CHOICE = 0, 2.191 ++ LZMA_LEN_CHOICE_2 = (LZMA_LEN_CHOICE + 1), 2.192 ++ LZMA_LEN_LOW = (LZMA_LEN_CHOICE_2 + 1), 2.193 ++ LZMA_LEN_MID = (LZMA_LEN_LOW \ 2.194 ++ + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))), 2.195 ++ LZMA_LEN_HIGH = (LZMA_LEN_MID \ 2.196 ++ + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))), 2.197 ++ LZMA_NUM_LEN_PROBS = (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)), 2.198 ++ 2.199 ++ LZMA_NUM_STATES = 12, 2.200 ++ LZMA_NUM_LIT_STATES = 7, 2.201 ++ 2.202 ++ LZMA_START_POS_MODEL_INDEX = 4, 2.203 ++ LZMA_END_POS_MODEL_INDEX = 14, 2.204 ++ LZMA_NUM_FULL_DISTANCES = (1 << (LZMA_END_POS_MODEL_INDEX >> 1)), 2.205 ++ 2.206 ++ LZMA_NUM_POS_SLOT_BITS = 6, 2.207 ++ LZMA_NUM_LEN_TO_POS_STATES = 4, 2.208 ++ 2.209 ++ LZMA_NUM_ALIGN_BITS = 4, 2.210 ++ 2.211 ++ LZMA_MATCH_MIN_LEN = 2, 2.212 ++ 2.213 ++ LZMA_IS_MATCH = 0, 2.214 ++ LZMA_IS_REP = (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)), 2.215 ++ LZMA_IS_REP_G0 = (LZMA_IS_REP + LZMA_NUM_STATES), 2.216 ++ LZMA_IS_REP_G1 = (LZMA_IS_REP_G0 + LZMA_NUM_STATES), 2.217 ++ LZMA_IS_REP_G2 = (LZMA_IS_REP_G1 + LZMA_NUM_STATES), 2.218 ++ LZMA_IS_REP_0_LONG = (LZMA_IS_REP_G2 + LZMA_NUM_STATES), 2.219 ++ LZMA_POS_SLOT = (LZMA_IS_REP_0_LONG \ 2.220 ++ + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)), 2.221 ++ LZMA_SPEC_POS = (LZMA_POS_SLOT \ 2.222 ++ + (LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)), 2.223 ++ LZMA_ALIGN = (LZMA_SPEC_POS \ 2.224 ++ + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX), 2.225 ++ LZMA_LEN_CODER = (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)), 2.226 ++ LZMA_REP_LEN_CODER = (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS), 2.227 ++ LZMA_LITERAL = (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS), 2.228 ++}; 2.229 ++ 2.230 ++ 2.231 ++void unlzma(char *from, char *to, char *heap) 2.232 ++{ 2.233 ++ lzma_header_t header; 2.234 ++ int lc, pb, lp; 2.235 ++ uint32_t pos_state_mask; 2.236 ++ uint32_t literal_pos_mask; 2.237 ++ uint16_t *p; 2.238 ++ rc_t *rc = (rc_t *) heap; 2.239 ++ int i; 2.240 ++ uint8_t *buffer = (void *) to; 2.241 ++ uint8_t previous_byte = 0; 2.242 ++ size_t buffer_pos = 0; 2.243 ++ int len = 0; 2.244 ++ int state = 0; 2.245 ++ uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; 2.246 ++ 2.247 ++ memcpy(&header, from, sizeof(header)); 2.248 ++ from += sizeof(header); 2.249 ++ heap += sizeof(*rc); 2.250 ++ rc->ptr = (void *) from; 2.251 ++ 2.252 ++ i = header.pos / 9; 2.253 ++ lc = header.pos % 9; 2.254 ++ pb = i / 5; 2.255 ++ lp = i % 5; 2.256 ++ pos_state_mask = (1 << pb) - 1; 2.257 ++ literal_pos_mask = (1 << lp) - 1; 2.258 ++ 2.259 ++ /* Example values from linux-3.3.4.tar.lzma: 2.260 ++ * dict_size: 64M, dst_size: 2^64-1 2.261 ++ */ 2.262 ++ header.dict_size = SWAP_LE32(header.dict_size); 2.263 ++ header.dst_size = SWAP_LE64(header.dst_size); 2.264 ++ 2.265 ++ //if (header.dict_size == 0) 2.266 ++ // header.dict_size++; 2.267 ++ 2.268 ++ rc_init(rc); 2.269 ++ 2.270 ++ { 2.271 ++ int num_probs; 2.272 ++ 2.273 ++ num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)); 2.274 ++ //p = xmalloc(num_probs * sizeof(*p)); 2.275 ++ p = (void *) heap; 2.276 ++ num_probs += LZMA_LITERAL - LZMA_BASE_SIZE; 2.277 ++ for (i = 0; i < num_probs; i++) 2.278 ++ p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; 2.279 ++ } 2.280 ++ 2.281 ++ 2.282 ++ while (buffer_pos < header.dst_size) { 2.283 ++ int pos_state = buffer_pos & pos_state_mask; 2.284 ++ uint16_t *prob = p + LZMA_IS_MATCH + (state << LZMA_NUM_POS_BITS_MAX) + pos_state; 2.285 ++ 2.286 ++ if (!rc_is_bit_1(rc, prob)) { 2.287 ++ static const char next_state[LZMA_NUM_STATES] = 2.288 ++ { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 }; 2.289 ++ int mi = 1; 2.290 ++ 2.291 ++ prob = (p + LZMA_LITERAL 2.292 ++ + (LZMA_LIT_SIZE * (((buffer_pos & literal_pos_mask) << lc) 2.293 ++ + (previous_byte >> (8 - lc)) 2.294 ++ ) 2.295 ++ ) 2.296 ++ ); 2.297 ++ 2.298 ++ if (state >= LZMA_NUM_LIT_STATES) { 2.299 ++ int match_byte; 2.300 ++ uint32_t pos = buffer_pos - rep0; 2.301 ++ 2.302 ++ while (pos >= header.dict_size) 2.303 ++ pos += header.dict_size; 2.304 ++ match_byte = buffer[pos]; 2.305 ++ do { 2.306 ++ int bit; 2.307 ++ 2.308 ++ match_byte <<= 1; 2.309 ++ bit = match_byte & 0x100; 2.310 ++ bit ^= (rc_get_bit(rc, prob + 0x100 + bit + mi, &mi) << 8); /* 0x100 or 0 */ 2.311 ++ if (bit) 2.312 ++ break; 2.313 ++ } while (mi < 0x100); 2.314 ++ } 2.315 ++ while (mi < 0x100) { 2.316 ++ rc_get_bit(rc, prob + mi, &mi); 2.317 ++ } 2.318 ++ 2.319 ++ state = next_state[state]; 2.320 ++ 2.321 ++ previous_byte = (uint8_t) mi; 2.322 ++ len = 1; 2.323 ++ goto one_byte2; 2.324 ++ } else { 2.325 ++ int num_bits; 2.326 ++ int offset; 2.327 ++ uint16_t *prob2; 2.328 ++#define prob_len prob2 2.329 ++ 2.330 ++ prob2 = p + LZMA_IS_REP + state; 2.331 ++ if (!rc_is_bit_1(rc, prob2)) { 2.332 ++ rep3 = rep2; 2.333 ++ rep2 = rep1; 2.334 ++ rep1 = rep0; 2.335 ++ state = state < LZMA_NUM_LIT_STATES ? 0 : 3; 2.336 ++ prob2 = p + LZMA_LEN_CODER; 2.337 ++ } else { 2.338 ++ prob2 += LZMA_IS_REP_G0 - LZMA_IS_REP; 2.339 ++ if (!rc_is_bit_1(rc, prob2)) { 2.340 ++ prob2 = (p + LZMA_IS_REP_0_LONG 2.341 ++ + (state << LZMA_NUM_POS_BITS_MAX) 2.342 ++ + pos_state 2.343 ++ ); 2.344 ++ if (!rc_is_bit_1(rc, prob2)) { 2.345 ++ state = state < LZMA_NUM_LIT_STATES ? 9 : 11; 2.346 ++ len = 1; 2.347 ++ goto string; 2.348 ++ } 2.349 ++ } else { 2.350 ++ uint32_t distance; 2.351 ++ 2.352 ++ prob2 += LZMA_IS_REP_G1 - LZMA_IS_REP_G0; 2.353 ++ distance = rep1; 2.354 ++ if (rc_is_bit_1(rc, prob2)) { 2.355 ++ prob2 += LZMA_IS_REP_G2 - LZMA_IS_REP_G1; 2.356 ++ distance = rep2; 2.357 ++ if (rc_is_bit_1(rc, prob2)) { 2.358 ++ distance = rep3; 2.359 ++ rep3 = rep2; 2.360 ++ } 2.361 ++ rep2 = rep1; 2.362 ++ } 2.363 ++ rep1 = rep0; 2.364 ++ rep0 = distance; 2.365 ++ } 2.366 ++ state = state < LZMA_NUM_LIT_STATES ? 8 : 11; 2.367 ++ prob2 = p + LZMA_REP_LEN_CODER; 2.368 ++ } 2.369 ++ 2.370 ++ prob_len = prob2 + LZMA_LEN_CHOICE; 2.371 ++ num_bits = LZMA_LEN_NUM_LOW_BITS; 2.372 ++ if (!rc_is_bit_1(rc, prob_len)) { 2.373 ++ prob_len += LZMA_LEN_LOW - LZMA_LEN_CHOICE 2.374 ++ + (pos_state << LZMA_LEN_NUM_LOW_BITS); 2.375 ++ offset = 0; 2.376 ++ } else { 2.377 ++ prob_len += LZMA_LEN_CHOICE_2 - LZMA_LEN_CHOICE; 2.378 ++ if (!rc_is_bit_1(rc, prob_len)) { 2.379 ++ prob_len += LZMA_LEN_MID - LZMA_LEN_CHOICE_2 2.380 ++ + (pos_state << LZMA_LEN_NUM_MID_BITS); 2.381 ++ offset = 1 << LZMA_LEN_NUM_LOW_BITS; 2.382 ++ num_bits += LZMA_LEN_NUM_MID_BITS - LZMA_LEN_NUM_LOW_BITS; 2.383 ++ } else { 2.384 ++ prob_len += LZMA_LEN_HIGH - LZMA_LEN_CHOICE_2; 2.385 ++ offset = ((1 << LZMA_LEN_NUM_LOW_BITS) 2.386 ++ + (1 << LZMA_LEN_NUM_MID_BITS)); 2.387 ++ num_bits += LZMA_LEN_NUM_HIGH_BITS - LZMA_LEN_NUM_LOW_BITS; 2.388 ++ } 2.389 ++ } 2.390 ++ rc_bit_tree_decode(rc, prob_len, num_bits, &len); 2.391 ++ len += offset; 2.392 ++ 2.393 ++ if (state < 4) { 2.394 ++ int pos_slot; 2.395 ++ uint16_t *prob3; 2.396 ++ 2.397 ++ state += LZMA_NUM_LIT_STATES; 2.398 ++ prob3 = p + LZMA_POS_SLOT + 2.399 ++ ((len < LZMA_NUM_LEN_TO_POS_STATES ? len : 2.400 ++ LZMA_NUM_LEN_TO_POS_STATES - 1) 2.401 ++ << LZMA_NUM_POS_SLOT_BITS); 2.402 ++ rc_bit_tree_decode(rc, prob3, 2.403 ++ LZMA_NUM_POS_SLOT_BITS, &pos_slot); 2.404 ++ rep0 = pos_slot; 2.405 ++ if (pos_slot >= LZMA_START_POS_MODEL_INDEX) { 2.406 ++ int i2, mi2, num_bits2 = (pos_slot >> 1) - 1; 2.407 ++ rep0 = 2 | (pos_slot & 1); 2.408 ++ if (pos_slot < LZMA_END_POS_MODEL_INDEX) { 2.409 ++ rep0 <<= num_bits2; 2.410 ++ prob3 = p + LZMA_SPEC_POS + rep0 - pos_slot - 1; 2.411 ++ } else { 2.412 ++ for (; num_bits2 != LZMA_NUM_ALIGN_BITS; num_bits2--) 2.413 ++ rep0 = (rep0 << 1) | rc_direct_bit(rc); 2.414 ++ rep0 <<= LZMA_NUM_ALIGN_BITS; 2.415 ++ prob3 = p + LZMA_ALIGN; 2.416 ++ } 2.417 ++ i2 = 1; 2.418 ++ mi2 = 1; 2.419 ++ while (num_bits2--) { 2.420 ++ if (rc_get_bit(rc, prob3 + mi2, &mi2)) 2.421 ++ rep0 |= i2; 2.422 ++ i2 <<= 1; 2.423 ++ } 2.424 ++ } 2.425 ++ if (++rep0 == 0) 2.426 ++ break; 2.427 ++ } 2.428 ++ 2.429 ++ len += LZMA_MATCH_MIN_LEN; 2.430 ++ string: 2.431 ++ do { 2.432 ++ uint32_t pos = buffer_pos - rep0; 2.433 ++ while (pos >= header.dict_size) 2.434 ++ pos += header.dict_size; 2.435 ++ previous_byte = buffer[pos]; 2.436 ++ one_byte2: 2.437 ++ buffer[buffer_pos++] = previous_byte; 2.438 ++ len--; 2.439 ++ } while (len != 0 && buffer_pos < header.dst_size); 2.440 ++ } 2.441 ++ } 2.442 ++} 2.443 +--- /dev/null 2.444 ++++ core/unlz4.c 2.445 +@@ -0,0 +1,112 @@ 2.446 ++/* 2.447 ++ * Copyright (C) 2015, pascal.bellard@slitaz.org 2.448 ++ * 2.449 ++ * This program is free software; you can redistribute it and/or modify 2.450 ++ * it under the terms of the GNU General Public License version 2 as 2.451 ++ * published by the Free Software Foundation. 2.452 ++ */ 2.453 ++ 2.454 ++#define LZ4_MAGIC 0x184D2204 /* Spec 1.5.0 */ 2.455 ++#define LZ4_LEGACY 0x184C2102 2.456 ++#define LZ4_SKIP(n) ((((n) - 0x184D2A50) >> 4) == 0) 2.457 ++ 2.458 ++static unsigned lz4cnt(unsigned char **p, unsigned n) 2.459 ++{ 2.460 ++ int i; 2.461 ++ 2.462 ++ if (n == 0xF) do { 2.463 ++ i = *(*p)++; 2.464 ++ n += i; 2.465 ++ } while (i == 0xFF); 2.466 ++ return n; 2.467 ++} 2.468 ++ 2.469 ++char *unlz4(unsigned char *from, unsigned char *end) 2.470 ++{ 2.471 ++ unsigned char *p, *end_chunk, *to, flags, mask; 2.472 ++ long magic; 2.473 ++ unsigned i, n, size; 2.474 ++ 2.475 ++ for (p = from, flags = size = 0; p < end;) { 2.476 ++ while (1) { 2.477 ++ magic = * (long *) p; 2.478 ++ p += sizeof(long); 2.479 ++ if (magic == LZ4_LEGACY) continue; 2.480 ++ if (magic != LZ4_MAGIC) break; 2.481 ++ flags = *p; 2.482 ++ if (flags & 8) { 2.483 ++ size = * (unsigned *) (p + 2); 2.484 ++ goto sizefound; 2.485 ++ } 2.486 ++ p += 3; /* skip FLG BD HC */ 2.487 ++ } 2.488 ++ if (LZ4_SKIP(magic)) { 2.489 ++ p += 4 + * (long *) p; 2.490 ++ continue; 2.491 ++ } 2.492 ++ mask = 4; /* Content checksum */ 2.493 ++ if (magic) { 2.494 ++ if (magic > 0) 2.495 ++ for (end_chunk = p + magic; p < end_chunk;) { 2.496 ++ unsigned char token = *p++; 2.497 ++ 2.498 ++ n = lz4cnt(&p, token >> 4); 2.499 ++ size += n; 2.500 ++ p += n; 2.501 ++ if (p >= end_chunk) break; 2.502 ++ p += sizeof(unsigned short); 2.503 ++ size += 4 + lz4cnt(&p, token & 0xF); 2.504 ++ } 2.505 ++ else { 2.506 ++ magic &= 0x7FffFFff; 2.507 ++ p += magic; 2.508 ++ size += magic; 2.509 ++ } 2.510 ++ mask = 0x10; /* Block checksum */ 2.511 ++ } 2.512 ++ if (flags & mask) p += 4; /* skip block checksum */ 2.513 ++ } 2.514 ++sizefound: 2.515 ++ size += 16 - (p - from); 2.516 ++ memmove(from + size, from, p - from); 2.517 ++ for (to = from, p = from += size, end += size, flags = 0; p < end;) { 2.518 ++ while (1) { 2.519 ++ magic = * (long *) p; 2.520 ++ p += sizeof(long); 2.521 ++ if (magic == LZ4_LEGACY) continue; 2.522 ++ if (magic != LZ4_MAGIC) break; 2.523 ++ flags = *p; 2.524 ++ if (flags & 8) p += 8; /* skip size */ 2.525 ++ p += 3; /* skip FLG BD HC */ 2.526 ++ } 2.527 ++ if (LZ4_SKIP(magic)) { 2.528 ++ p += 4 + * (long *) p; 2.529 ++ continue; 2.530 ++ } 2.531 ++ mask = 4; /* Content checksum */ 2.532 ++ if (magic) { 2.533 ++ if (magic > 0) 2.534 ++ for (end_chunk = p + magic; p < end_chunk;) { 2.535 ++ char *dico; 2.536 ++ unsigned char token = *p++; 2.537 ++ 2.538 ++ n = lz4cnt(&p, token >> 4); 2.539 ++ for (i = 0; i < n; i++) 2.540 ++ *to++ = *p++; 2.541 ++ if (p >= end_chunk) break; 2.542 ++ dico = to - (* (unsigned short *) p); 2.543 ++ p += sizeof(unsigned short); 2.544 ++ n = 4 + lz4cnt(&p, token & 0xF); 2.545 ++ for (i = 0; i < n; i++) 2.546 ++ *to++ = *dico++; 2.547 ++ } 2.548 ++ else for (end_chunk = p + (magic & 0x7FffFFff); 2.549 ++ p < end_chunk;) { 2.550 ++ *to++ = *p++; 2.551 ++ } 2.552 ++ mask = 0x10; /* Block checksum */ 2.553 ++ } 2.554 ++ if (flags & mask) p += 4; /* Skip checksum */ 2.555 ++ } 2.556 ++ return to; 2.557 ++}