wok 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 ++}