wok annotate syslinux/stuff/extra/loadhigh.u @ rev 25057

linux-libre: fix linux-libre-3.18.129-gnu-slitaz.config
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon Jun 06 11:05:30 2022 +0000 (2022-06-06)
parents d94dea3c101e
children
rev   line source
pascal@18757 1 --- core/fs/loadhigh.c
pascal@18757 2 +++ core/fs/loadhigh.c
pascal@18757 3 @@ -36,6 +36,11 @@
pascal@18757 4 #include <minmax.h>
pascal@18757 5 #include "core.h"
pascal@18757 6 #include "fs.h"
pascal@18757 7 +#define LZLOAD ".c32 modules can be compressed with lz4 or lzma"
pascal@18757 8 +#ifdef LZLOAD
pascal@18757 9 +#include "../unlz4.c"
pascal@18757 10 +#include "../unlzma.c"
pascal@18757 11 +#endif
pascal@18757 12
pascal@18757 13 #define MAX_CHUNK (1 << 20) /* 1 MB */
pascal@18757 14
pascal@18801 15 @@ -51,6 +56,9 @@
pascal@18757 16 uint32_t sector_mask;
pascal@18757 17 size_t pad;
pascal@18757 18 uint32_t retflags = 0;
pascal@18757 19 +#ifdef LZLOAD
pascal@18757 20 + char *unpacked = (char *) regs->edi.l;
pascal@18757 21 +#endif
pascal@18757 22
pascal@18757 23 bytes = regs->eax.l;
pascal@18757 24 zero_mask = regs->edx.w[0];
pascal@18801 25 @@ -101,6 +109,27 @@
pascal@18757 26 break;
pascal@18757 27 }
pascal@18757 28 }
pascal@18757 29 +
pascal@18757 30 +#ifdef LZLOAD
pascal@18757 31 + switch (* (short *) unpacked) {
pascal@18757 32 + char *packed;
pascal@18801 33 + size_t packedsz, unpackedsz;
pascal@18757 34 + case 0x005D:
pascal@18801 35 + packedsz = buf - unpacked;
pascal@18801 36 + unpackedsz = * (unsigned long *) (unpacked + 5);
pascal@18801 37 + if (unpackedsz > 1000000) break; /* no size? */
pascal@18801 38 + packed = unpacked + unpackedsz - packedsz + 1024;
pascal@18801 39 + if (packed < unpacked + 1024) packed = unpacked + 1024;
pascal@18801 40 + memmove(packed, unpacked, packedsz);
pascal@18801 41 + unlzma(packed, unpacked, packed + packedsz /* heap */);
pascal@18757 42 + buf = packed;
pascal@18757 43 + break;
pascal@18757 44 + case 0x2204:
pascal@18757 45 + case 0x2102:
pascal@18759 46 + buf = (char *) unlz4((unsigned char *) unpacked, (unsigned char *) buf);
pascal@18757 47 + break;
pascal@18757 48 + }
pascal@18757 49 +#endif
pascal@18757 50
pascal@18757 51 pad = (size_t)buf & zero_mask;
pascal@18757 52 if (pad)
pascal@18757 53 --- /dev/null
pascal@18757 54 +++ core/unlzma.c
pascal@18759 55 @@ -0,0 +1,385 @@
pascal@18757 56 +typedef unsigned char uint8_t;
pascal@18757 57 +typedef unsigned short uint16_t;
pascal@18757 58 +typedef unsigned uint32_t;
pascal@18757 59 +typedef unsigned long long uint64_t;
pascal@18757 60 +typedef unsigned size_t;
pascal@18757 61 +#define SWAP_LE32(x) (x)
pascal@18757 62 +#define SWAP_LE64(x) (x)
pascal@18757 63 +/* vi: set sw=4 ts=4: */
pascal@18757 64 +/*
pascal@18757 65 + * Small lzma deflate implementation.
pascal@18757 66 + * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
pascal@18757 67 + *
pascal@18757 68 + * Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/)
pascal@18757 69 + * Copyright (C) 1999-2005 Igor Pavlov
pascal@18757 70 + *
pascal@18757 71 + * Licensed under GPLv2 or later, see file LICENSE in this source tree.
pascal@18757 72 + */
pascal@18757 73 +
pascal@18759 74 +#include <string.h>
pascal@18759 75 +
pascal@18757 76 +#define PACKED __attribute__ ((packed))
pascal@18757 77 +#define ALWAYS_INLINE inline
pascal@18757 78 +#define speed_inline
pascal@18757 79 +#define size_inline ALWAYS_INLINE
pascal@18757 80 +
pascal@18757 81 +
pascal@18757 82 +typedef struct {
pascal@18757 83 + uint8_t *ptr;
pascal@18757 84 +
pascal@18757 85 + uint32_t code;
pascal@18757 86 + uint32_t range;
pascal@18757 87 + uint32_t bound;
pascal@18757 88 +} rc_t;
pascal@18757 89 +
pascal@18757 90 +#define RC_TOP_BITS 24
pascal@18757 91 +#define RC_MOVE_BITS 5
pascal@18757 92 +#define RC_MODEL_TOTAL_BITS 11
pascal@18757 93 +
pascal@18757 94 +/* Called twice, but one callsite is in speed_inline'd rc_is_bit_1() */
pascal@18757 95 +static void rc_do_normalize(rc_t *rc)
pascal@18757 96 +{
pascal@18757 97 + rc->range <<= 8;
pascal@18757 98 + rc->code = (rc->code << 8) | *rc->ptr++;
pascal@18757 99 +}
pascal@18757 100 +
pascal@18757 101 +static ALWAYS_INLINE void rc_normalize(rc_t *rc)
pascal@18757 102 +{
pascal@18757 103 + if (rc->range < (1 << RC_TOP_BITS)) {
pascal@18757 104 + rc_do_normalize(rc);
pascal@18757 105 + }
pascal@18757 106 +}
pascal@18757 107 +
pascal@18757 108 +/* Called once */
pascal@18757 109 +static void rc_init(rc_t *rc) /*, int buffer_size) */
pascal@18757 110 +{
pascal@18757 111 + int i;
pascal@18757 112 +
pascal@18757 113 + rc->range = 0;
pascal@18757 114 + for (i = 0; i < 5; i++) {
pascal@18757 115 + rc_do_normalize(rc);
pascal@18757 116 + }
pascal@18757 117 + rc->range = 0xffffffff;
pascal@18757 118 +}
pascal@18757 119 +
pascal@18757 120 +/* rc_is_bit_1 is called 9 times */
pascal@18757 121 +static speed_inline int rc_is_bit_1(rc_t *rc, uint16_t *p)
pascal@18757 122 +{
pascal@18757 123 + rc_normalize(rc);
pascal@18757 124 + rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS);
pascal@18757 125 + if (rc->code < rc->bound) {
pascal@18757 126 + rc->range = rc->bound;
pascal@18757 127 + *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS;
pascal@18757 128 + return 0;
pascal@18757 129 + }
pascal@18757 130 + rc->range -= rc->bound;
pascal@18757 131 + rc->code -= rc->bound;
pascal@18757 132 + *p -= *p >> RC_MOVE_BITS;
pascal@18757 133 + return 1;
pascal@18757 134 +}
pascal@18757 135 +
pascal@18757 136 +/* Called 4 times in unlzma loop */
pascal@18757 137 +static ALWAYS_INLINE int rc_get_bit(rc_t *rc, uint16_t *p, int *symbol)
pascal@18757 138 +{
pascal@18757 139 + int ret = rc_is_bit_1(rc, p);
pascal@18757 140 + *symbol = *symbol * 2 + ret;
pascal@18757 141 + return ret;
pascal@18757 142 +}
pascal@18757 143 +
pascal@18757 144 +/* Called once */
pascal@18757 145 +static ALWAYS_INLINE int rc_direct_bit(rc_t *rc)
pascal@18757 146 +{
pascal@18757 147 + rc_normalize(rc);
pascal@18757 148 + rc->range >>= 1;
pascal@18757 149 + if (rc->code >= rc->range) {
pascal@18757 150 + rc->code -= rc->range;
pascal@18757 151 + return 1;
pascal@18757 152 + }
pascal@18757 153 + return 0;
pascal@18757 154 +}
pascal@18757 155 +
pascal@18757 156 +/* Called twice */
pascal@18757 157 +static speed_inline void
pascal@18757 158 +rc_bit_tree_decode(rc_t *rc, uint16_t *p, int num_levels, int *symbol)
pascal@18757 159 +{
pascal@18757 160 + int i = num_levels;
pascal@18757 161 +
pascal@18757 162 + *symbol = 1;
pascal@18757 163 + while (i--)
pascal@18757 164 + rc_get_bit(rc, p + *symbol, symbol);
pascal@18757 165 + *symbol -= 1 << num_levels;
pascal@18757 166 +}
pascal@18757 167 +
pascal@18757 168 +
pascal@18757 169 +typedef struct {
pascal@18757 170 + uint8_t pos;
pascal@18757 171 + uint32_t dict_size;
pascal@18757 172 + uint64_t dst_size;
pascal@18757 173 +} PACKED lzma_header_t;
pascal@18757 174 +
pascal@18757 175 +
pascal@18757 176 +/* #defines will force compiler to compute/optimize each one with each usage.
pascal@18757 177 + * Have heart and use enum instead. */
pascal@18757 178 +enum {
pascal@18757 179 + LZMA_BASE_SIZE = 1846,
pascal@18757 180 + LZMA_LIT_SIZE = 768,
pascal@18757 181 +
pascal@18757 182 + LZMA_NUM_POS_BITS_MAX = 4,
pascal@18757 183 +
pascal@18757 184 + LZMA_LEN_NUM_LOW_BITS = 3,
pascal@18757 185 + LZMA_LEN_NUM_MID_BITS = 3,
pascal@18757 186 + LZMA_LEN_NUM_HIGH_BITS = 8,
pascal@18757 187 +
pascal@18757 188 + LZMA_LEN_CHOICE = 0,
pascal@18757 189 + LZMA_LEN_CHOICE_2 = (LZMA_LEN_CHOICE + 1),
pascal@18757 190 + LZMA_LEN_LOW = (LZMA_LEN_CHOICE_2 + 1),
pascal@18757 191 + LZMA_LEN_MID = (LZMA_LEN_LOW \
pascal@18757 192 + + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))),
pascal@18757 193 + LZMA_LEN_HIGH = (LZMA_LEN_MID \
pascal@18757 194 + + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))),
pascal@18757 195 + LZMA_NUM_LEN_PROBS = (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)),
pascal@18757 196 +
pascal@18757 197 + LZMA_NUM_STATES = 12,
pascal@18757 198 + LZMA_NUM_LIT_STATES = 7,
pascal@18757 199 +
pascal@18757 200 + LZMA_START_POS_MODEL_INDEX = 4,
pascal@18757 201 + LZMA_END_POS_MODEL_INDEX = 14,
pascal@18757 202 + LZMA_NUM_FULL_DISTANCES = (1 << (LZMA_END_POS_MODEL_INDEX >> 1)),
pascal@18757 203 +
pascal@18757 204 + LZMA_NUM_POS_SLOT_BITS = 6,
pascal@18757 205 + LZMA_NUM_LEN_TO_POS_STATES = 4,
pascal@18757 206 +
pascal@18757 207 + LZMA_NUM_ALIGN_BITS = 4,
pascal@18757 208 +
pascal@18757 209 + LZMA_MATCH_MIN_LEN = 2,
pascal@18757 210 +
pascal@18757 211 + LZMA_IS_MATCH = 0,
pascal@18757 212 + LZMA_IS_REP = (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)),
pascal@18757 213 + LZMA_IS_REP_G0 = (LZMA_IS_REP + LZMA_NUM_STATES),
pascal@18757 214 + LZMA_IS_REP_G1 = (LZMA_IS_REP_G0 + LZMA_NUM_STATES),
pascal@18757 215 + LZMA_IS_REP_G2 = (LZMA_IS_REP_G1 + LZMA_NUM_STATES),
pascal@18757 216 + LZMA_IS_REP_0_LONG = (LZMA_IS_REP_G2 + LZMA_NUM_STATES),
pascal@18757 217 + LZMA_POS_SLOT = (LZMA_IS_REP_0_LONG \
pascal@18757 218 + + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)),
pascal@18757 219 + LZMA_SPEC_POS = (LZMA_POS_SLOT \
pascal@18757 220 + + (LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)),
pascal@18757 221 + LZMA_ALIGN = (LZMA_SPEC_POS \
pascal@18757 222 + + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX),
pascal@18757 223 + LZMA_LEN_CODER = (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)),
pascal@18757 224 + LZMA_REP_LEN_CODER = (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS),
pascal@18757 225 + LZMA_LITERAL = (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS),
pascal@18757 226 +};
pascal@18757 227 +
pascal@18757 228 +
pascal@18757 229 +void unlzma(char *from, char *to, char *heap)
pascal@18757 230 +{
pascal@18757 231 + lzma_header_t header;
pascal@18757 232 + int lc, pb, lp;
pascal@18757 233 + uint32_t pos_state_mask;
pascal@18757 234 + uint32_t literal_pos_mask;
pascal@18757 235 + uint16_t *p;
pascal@18757 236 + rc_t *rc = (rc_t *) heap;
pascal@18757 237 + int i;
pascal@18757 238 + uint8_t *buffer = (void *) to;
pascal@18757 239 + uint8_t previous_byte = 0;
pascal@18757 240 + size_t buffer_pos = 0;
pascal@18757 241 + int len = 0;
pascal@18757 242 + int state = 0;
pascal@18757 243 + uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
pascal@18757 244 +
pascal@18757 245 + memcpy(&header, from, sizeof(header));
pascal@18757 246 + from += sizeof(header);
pascal@18757 247 + heap += sizeof(*rc);
pascal@18757 248 + rc->ptr = (void *) from;
pascal@18757 249 +
pascal@18757 250 + i = header.pos / 9;
pascal@18757 251 + lc = header.pos % 9;
pascal@18757 252 + pb = i / 5;
pascal@18757 253 + lp = i % 5;
pascal@18757 254 + pos_state_mask = (1 << pb) - 1;
pascal@18757 255 + literal_pos_mask = (1 << lp) - 1;
pascal@18757 256 +
pascal@18757 257 + /* Example values from linux-3.3.4.tar.lzma:
pascal@18757 258 + * dict_size: 64M, dst_size: 2^64-1
pascal@18757 259 + */
pascal@18757 260 + header.dict_size = SWAP_LE32(header.dict_size);
pascal@18757 261 + header.dst_size = SWAP_LE64(header.dst_size);
pascal@18757 262 +
pascal@18757 263 + //if (header.dict_size == 0)
pascal@18757 264 + // header.dict_size++;
pascal@18757 265 +
pascal@18757 266 + rc_init(rc);
pascal@18757 267 +
pascal@18757 268 + {
pascal@18757 269 + int num_probs;
pascal@18757 270 +
pascal@18757 271 + num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp));
pascal@18757 272 + //p = xmalloc(num_probs * sizeof(*p));
pascal@18757 273 + p = (void *) heap;
pascal@18757 274 + num_probs += LZMA_LITERAL - LZMA_BASE_SIZE;
pascal@18757 275 + for (i = 0; i < num_probs; i++)
pascal@18757 276 + p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
pascal@18757 277 + }
pascal@18757 278 +
pascal@18757 279 +
pascal@18757 280 + while (buffer_pos < header.dst_size) {
pascal@18757 281 + int pos_state = buffer_pos & pos_state_mask;
pascal@18757 282 + uint16_t *prob = p + LZMA_IS_MATCH + (state << LZMA_NUM_POS_BITS_MAX) + pos_state;
pascal@18757 283 +
pascal@18757 284 + if (!rc_is_bit_1(rc, prob)) {
pascal@18757 285 + static const char next_state[LZMA_NUM_STATES] =
pascal@18757 286 + { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
pascal@18757 287 + int mi = 1;
pascal@18757 288 +
pascal@18757 289 + prob = (p + LZMA_LITERAL
pascal@18757 290 + + (LZMA_LIT_SIZE * (((buffer_pos & literal_pos_mask) << lc)
pascal@18757 291 + + (previous_byte >> (8 - lc))
pascal@18757 292 + )
pascal@18757 293 + )
pascal@18757 294 + );
pascal@18757 295 +
pascal@18757 296 + if (state >= LZMA_NUM_LIT_STATES) {
pascal@18757 297 + int match_byte;
pascal@18757 298 + uint32_t pos = buffer_pos - rep0;
pascal@18757 299 +
pascal@18757 300 + while (pos >= header.dict_size)
pascal@18757 301 + pos += header.dict_size;
pascal@18757 302 + match_byte = buffer[pos];
pascal@18757 303 + do {
pascal@18757 304 + int bit;
pascal@18757 305 +
pascal@18757 306 + match_byte <<= 1;
pascal@18757 307 + bit = match_byte & 0x100;
pascal@18757 308 + bit ^= (rc_get_bit(rc, prob + 0x100 + bit + mi, &mi) << 8); /* 0x100 or 0 */
pascal@18757 309 + if (bit)
pascal@18757 310 + break;
pascal@18757 311 + } while (mi < 0x100);
pascal@18757 312 + }
pascal@18757 313 + while (mi < 0x100) {
pascal@18757 314 + rc_get_bit(rc, prob + mi, &mi);
pascal@18757 315 + }
pascal@18757 316 +
pascal@18757 317 + state = next_state[state];
pascal@18757 318 +
pascal@18757 319 + previous_byte = (uint8_t) mi;
pascal@18757 320 + len = 1;
pascal@18757 321 + goto one_byte2;
pascal@18757 322 + } else {
pascal@18757 323 + int num_bits;
pascal@18757 324 + int offset;
pascal@18757 325 + uint16_t *prob2;
pascal@18757 326 +#define prob_len prob2
pascal@18757 327 +
pascal@18757 328 + prob2 = p + LZMA_IS_REP + state;
pascal@18757 329 + if (!rc_is_bit_1(rc, prob2)) {
pascal@18757 330 + rep3 = rep2;
pascal@18757 331 + rep2 = rep1;
pascal@18757 332 + rep1 = rep0;
pascal@18757 333 + state = state < LZMA_NUM_LIT_STATES ? 0 : 3;
pascal@18757 334 + prob2 = p + LZMA_LEN_CODER;
pascal@18757 335 + } else {
pascal@18757 336 + prob2 += LZMA_IS_REP_G0 - LZMA_IS_REP;
pascal@18757 337 + if (!rc_is_bit_1(rc, prob2)) {
pascal@18757 338 + prob2 = (p + LZMA_IS_REP_0_LONG
pascal@18757 339 + + (state << LZMA_NUM_POS_BITS_MAX)
pascal@18757 340 + + pos_state
pascal@18757 341 + );
pascal@18757 342 + if (!rc_is_bit_1(rc, prob2)) {
pascal@18757 343 + state = state < LZMA_NUM_LIT_STATES ? 9 : 11;
pascal@18757 344 + len = 1;
pascal@18757 345 + goto string;
pascal@18757 346 + }
pascal@18757 347 + } else {
pascal@18757 348 + uint32_t distance;
pascal@18757 349 +
pascal@18757 350 + prob2 += LZMA_IS_REP_G1 - LZMA_IS_REP_G0;
pascal@18757 351 + distance = rep1;
pascal@18757 352 + if (rc_is_bit_1(rc, prob2)) {
pascal@18757 353 + prob2 += LZMA_IS_REP_G2 - LZMA_IS_REP_G1;
pascal@18757 354 + distance = rep2;
pascal@18757 355 + if (rc_is_bit_1(rc, prob2)) {
pascal@18757 356 + distance = rep3;
pascal@18757 357 + rep3 = rep2;
pascal@18757 358 + }
pascal@18757 359 + rep2 = rep1;
pascal@18757 360 + }
pascal@18757 361 + rep1 = rep0;
pascal@18757 362 + rep0 = distance;
pascal@18757 363 + }
pascal@18757 364 + state = state < LZMA_NUM_LIT_STATES ? 8 : 11;
pascal@18757 365 + prob2 = p + LZMA_REP_LEN_CODER;
pascal@18757 366 + }
pascal@18757 367 +
pascal@18757 368 + prob_len = prob2 + LZMA_LEN_CHOICE;
pascal@18757 369 + num_bits = LZMA_LEN_NUM_LOW_BITS;
pascal@18757 370 + if (!rc_is_bit_1(rc, prob_len)) {
pascal@18757 371 + prob_len += LZMA_LEN_LOW - LZMA_LEN_CHOICE
pascal@18757 372 + + (pos_state << LZMA_LEN_NUM_LOW_BITS);
pascal@18757 373 + offset = 0;
pascal@18757 374 + } else {
pascal@18757 375 + prob_len += LZMA_LEN_CHOICE_2 - LZMA_LEN_CHOICE;
pascal@18757 376 + if (!rc_is_bit_1(rc, prob_len)) {
pascal@18757 377 + prob_len += LZMA_LEN_MID - LZMA_LEN_CHOICE_2
pascal@18757 378 + + (pos_state << LZMA_LEN_NUM_MID_BITS);
pascal@18757 379 + offset = 1 << LZMA_LEN_NUM_LOW_BITS;
pascal@18757 380 + num_bits += LZMA_LEN_NUM_MID_BITS - LZMA_LEN_NUM_LOW_BITS;
pascal@18757 381 + } else {
pascal@18757 382 + prob_len += LZMA_LEN_HIGH - LZMA_LEN_CHOICE_2;
pascal@18757 383 + offset = ((1 << LZMA_LEN_NUM_LOW_BITS)
pascal@18757 384 + + (1 << LZMA_LEN_NUM_MID_BITS));
pascal@18757 385 + num_bits += LZMA_LEN_NUM_HIGH_BITS - LZMA_LEN_NUM_LOW_BITS;
pascal@18757 386 + }
pascal@18757 387 + }
pascal@18757 388 + rc_bit_tree_decode(rc, prob_len, num_bits, &len);
pascal@18757 389 + len += offset;
pascal@18757 390 +
pascal@18757 391 + if (state < 4) {
pascal@18757 392 + int pos_slot;
pascal@18757 393 + uint16_t *prob3;
pascal@18757 394 +
pascal@18757 395 + state += LZMA_NUM_LIT_STATES;
pascal@18757 396 + prob3 = p + LZMA_POS_SLOT +
pascal@18757 397 + ((len < LZMA_NUM_LEN_TO_POS_STATES ? len :
pascal@18757 398 + LZMA_NUM_LEN_TO_POS_STATES - 1)
pascal@18757 399 + << LZMA_NUM_POS_SLOT_BITS);
pascal@18757 400 + rc_bit_tree_decode(rc, prob3,
pascal@18757 401 + LZMA_NUM_POS_SLOT_BITS, &pos_slot);
pascal@18757 402 + rep0 = pos_slot;
pascal@18757 403 + if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
pascal@18757 404 + int i2, mi2, num_bits2 = (pos_slot >> 1) - 1;
pascal@18757 405 + rep0 = 2 | (pos_slot & 1);
pascal@18757 406 + if (pos_slot < LZMA_END_POS_MODEL_INDEX) {
pascal@18757 407 + rep0 <<= num_bits2;
pascal@18757 408 + prob3 = p + LZMA_SPEC_POS + rep0 - pos_slot - 1;
pascal@18757 409 + } else {
pascal@18757 410 + for (; num_bits2 != LZMA_NUM_ALIGN_BITS; num_bits2--)
pascal@18757 411 + rep0 = (rep0 << 1) | rc_direct_bit(rc);
pascal@18757 412 + rep0 <<= LZMA_NUM_ALIGN_BITS;
pascal@18757 413 + prob3 = p + LZMA_ALIGN;
pascal@18757 414 + }
pascal@18757 415 + i2 = 1;
pascal@18757 416 + mi2 = 1;
pascal@18757 417 + while (num_bits2--) {
pascal@18757 418 + if (rc_get_bit(rc, prob3 + mi2, &mi2))
pascal@18757 419 + rep0 |= i2;
pascal@18757 420 + i2 <<= 1;
pascal@18757 421 + }
pascal@18757 422 + }
pascal@18757 423 + if (++rep0 == 0)
pascal@18757 424 + break;
pascal@18757 425 + }
pascal@18757 426 +
pascal@18757 427 + len += LZMA_MATCH_MIN_LEN;
pascal@18757 428 + string:
pascal@18757 429 + do {
pascal@18757 430 + uint32_t pos = buffer_pos - rep0;
pascal@18757 431 + while (pos >= header.dict_size)
pascal@18757 432 + pos += header.dict_size;
pascal@18757 433 + previous_byte = buffer[pos];
pascal@18757 434 + one_byte2:
pascal@18757 435 + buffer[buffer_pos++] = previous_byte;
pascal@18757 436 + len--;
pascal@18757 437 + } while (len != 0 && buffer_pos < header.dst_size);
pascal@18757 438 + }
pascal@18757 439 + }
pascal@18757 440 +}
pascal@18757 441 --- /dev/null
pascal@18757 442 +++ core/unlz4.c
pascal@18759 443 @@ -0,0 +1,114 @@
pascal@18757 444 +/*
pascal@18757 445 + * Copyright (C) 2015, pascal.bellard@slitaz.org
pascal@18757 446 + *
pascal@18757 447 + * This program is free software; you can redistribute it and/or modify
pascal@18757 448 + * it under the terms of the GNU General Public License version 2 as
pascal@18757 449 + * published by the Free Software Foundation.
pascal@18757 450 + */
pascal@18757 451 +
pascal@18759 452 +#include <string.h>
pascal@18759 453 +
pascal@18757 454 +#define LZ4_MAGIC 0x184D2204 /* Spec 1.5.0 */
pascal@18757 455 +#define LZ4_LEGACY 0x184C2102
pascal@18757 456 +#define LZ4_SKIP(n) ((((n) - 0x184D2A50) >> 4) == 0)
pascal@18757 457 +
pascal@18757 458 +static unsigned lz4cnt(unsigned char **p, unsigned n)
pascal@18757 459 +{
pascal@18757 460 + int i;
pascal@18757 461 +
pascal@18757 462 + if (n == 0xF) do {
pascal@18757 463 + i = *(*p)++;
pascal@18757 464 + n += i;
pascal@18757 465 + } while (i == 0xFF);
pascal@18757 466 + return n;
pascal@18757 467 +}
pascal@18757 468 +
pascal@18759 469 +unsigned char *unlz4(unsigned char *from, unsigned char *end)
pascal@18757 470 +{
pascal@18757 471 + unsigned char *p, *end_chunk, *to, flags, mask;
pascal@18757 472 + long magic;
pascal@18757 473 + unsigned i, n, size;
pascal@18757 474 +
pascal@18757 475 + for (p = from, flags = size = 0; p < end;) {
pascal@18757 476 + while (1) {
pascal@18757 477 + magic = * (long *) p;
pascal@18757 478 + p += sizeof(long);
pascal@18757 479 + if (magic == LZ4_LEGACY) continue;
pascal@18757 480 + if (magic != LZ4_MAGIC) break;
pascal@18757 481 + flags = *p;
pascal@18757 482 + if (flags & 8) {
pascal@18757 483 + size = * (unsigned *) (p + 2);
pascal@18757 484 + goto sizefound;
pascal@18757 485 + }
pascal@18757 486 + p += 3; /* skip FLG BD HC */
pascal@18757 487 + }
pascal@18757 488 + if (LZ4_SKIP(magic)) {
pascal@18757 489 + p += 4 + * (long *) p;
pascal@18757 490 + continue;
pascal@18757 491 + }
pascal@18757 492 + mask = 4; /* Content checksum */
pascal@18757 493 + if (magic) {
pascal@18757 494 + if (magic > 0)
pascal@18757 495 + for (end_chunk = p + magic; p < end_chunk;) {
pascal@18757 496 + unsigned char token = *p++;
pascal@18757 497 +
pascal@18757 498 + n = lz4cnt(&p, token >> 4);
pascal@18757 499 + size += n;
pascal@18757 500 + p += n;
pascal@18757 501 + if (p >= end_chunk) break;
pascal@18757 502 + p += sizeof(unsigned short);
pascal@18757 503 + size += 4 + lz4cnt(&p, token & 0xF);
pascal@18757 504 + }
pascal@18757 505 + else {
pascal@18757 506 + magic &= 0x7FffFFff;
pascal@18757 507 + p += magic;
pascal@18757 508 + size += magic;
pascal@18757 509 + }
pascal@18757 510 + mask = 0x10; /* Block checksum */
pascal@18757 511 + }
pascal@18757 512 + if (flags & mask) p += 4; /* skip block checksum */
pascal@18757 513 + }
pascal@18757 514 +sizefound:
pascal@18757 515 + size += 16 - (p - from);
pascal@18757 516 + memmove(from + size, from, p - from);
pascal@18757 517 + for (to = from, p = from += size, end += size, flags = 0; p < end;) {
pascal@18757 518 + while (1) {
pascal@18757 519 + magic = * (long *) p;
pascal@18757 520 + p += sizeof(long);
pascal@18757 521 + if (magic == LZ4_LEGACY) continue;
pascal@18757 522 + if (magic != LZ4_MAGIC) break;
pascal@18757 523 + flags = *p;
pascal@18757 524 + if (flags & 8) p += 8; /* skip size */
pascal@18757 525 + p += 3; /* skip FLG BD HC */
pascal@18757 526 + }
pascal@18757 527 + if (LZ4_SKIP(magic)) {
pascal@18757 528 + p += 4 + * (long *) p;
pascal@18757 529 + continue;
pascal@18757 530 + }
pascal@18757 531 + mask = 4; /* Content checksum */
pascal@18757 532 + if (magic) {
pascal@18757 533 + if (magic > 0)
pascal@18757 534 + for (end_chunk = p + magic; p < end_chunk;) {
pascal@18758 535 + unsigned char *dico;
pascal@18757 536 + unsigned char token = *p++;
pascal@18757 537 +
pascal@18757 538 + n = lz4cnt(&p, token >> 4);
pascal@18757 539 + for (i = 0; i < n; i++)
pascal@18757 540 + *to++ = *p++;
pascal@18757 541 + if (p >= end_chunk) break;
pascal@18757 542 + dico = to - (* (unsigned short *) p);
pascal@18757 543 + p += sizeof(unsigned short);
pascal@18757 544 + n = 4 + lz4cnt(&p, token & 0xF);
pascal@18757 545 + for (i = 0; i < n; i++)
pascal@18757 546 + *to++ = *dico++;
pascal@18757 547 + }
pascal@18757 548 + else for (end_chunk = p + (magic & 0x7FffFFff);
pascal@18757 549 + p < end_chunk;) {
pascal@18757 550 + *to++ = *p++;
pascal@18757 551 + }
pascal@18757 552 + mask = 0x10; /* Block checksum */
pascal@18757 553 + }
pascal@18757 554 + if (flags & mask) p += 4; /* Skip checksum */
pascal@18757 555 + }
pascal@18757 556 + return to;
pascal@18757 557 +}