wok diff syslinux/stuff/extra/loadhigh.u @ 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 | |
children | 924e6ea5da10 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/syslinux/stuff/extra/loadhigh.u Tue Dec 29 08:59:31 2015 +0100 1.3 @@ -0,0 +1,554 @@ 1.4 +--- core/fs/loadhigh.c 1.5 ++++ core/fs/loadhigh.c 1.6 +@@ -36,6 +36,11 @@ 1.7 + #include <minmax.h> 1.8 + #include "core.h" 1.9 + #include "fs.h" 1.10 ++#define LZLOAD ".c32 modules can be compressed with lz4 or lzma" 1.11 ++#ifdef LZLOAD 1.12 ++#include "../unlz4.c" 1.13 ++#include "../unlzma.c" 1.14 ++#endif 1.15 + 1.16 + #define MAX_CHUNK (1 << 20) /* 1 MB */ 1.17 + 1.18 +@@ -51,6 +56,10 @@ 1.19 + uint32_t sector_mask; 1.20 + size_t pad; 1.21 + uint32_t retflags = 0; 1.22 ++#ifdef LZLOAD 1.23 ++ char *unpacked = (char *) regs->edi.l; 1.24 ++ size_t unpackedsz; 1.25 ++#endif 1.26 + 1.27 + bytes = regs->eax.l; 1.28 + zero_mask = regs->edx.w[0]; 1.29 +@@ -101,6 +110,27 @@ 1.30 + break; 1.31 + } 1.32 + } 1.33 ++ 1.34 ++#ifdef LZLOAD 1.35 ++ unpackedsz = buf - unpacked; 1.36 ++ switch (* (short *) unpacked) { 1.37 ++ char *packed; 1.38 ++ case 0x005D: 1.39 ++ packed = unpacked + * (unsigned long *) (unpacked + 5) 1.40 ++ - unpackedsz + 1024; 1.41 ++ 1.42 ++ if (packed < unpacked + 1024) 1.43 ++ packed = unpacked + 1024; 1.44 ++ memmove(packed, unpacked, unpackedsz); 1.45 ++ unlzma(packed, unpacked, packed + unpackedsz /* head */); 1.46 ++ buf = packed; 1.47 ++ break; 1.48 ++ case 0x2204: 1.49 ++ case 0x2102: 1.50 ++ buf = unlz4(unpacked, buf); 1.51 ++ break; 1.52 ++ } 1.53 ++#endif 1.54 + 1.55 + pad = (size_t)buf & zero_mask; 1.56 + if (pad) 1.57 +--- /dev/null 1.58 ++++ core/unlzma.c 1.59 +@@ -0,0 +1,383 @@ 1.60 ++typedef unsigned char uint8_t; 1.61 ++typedef unsigned short uint16_t; 1.62 ++typedef unsigned uint32_t; 1.63 ++typedef unsigned long long uint64_t; 1.64 ++typedef unsigned size_t; 1.65 ++#define SWAP_LE32(x) (x) 1.66 ++#define SWAP_LE64(x) (x) 1.67 ++/* vi: set sw=4 ts=4: */ 1.68 ++/* 1.69 ++ * Small lzma deflate implementation. 1.70 ++ * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> 1.71 ++ * 1.72 ++ * Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/) 1.73 ++ * Copyright (C) 1999-2005 Igor Pavlov 1.74 ++ * 1.75 ++ * Licensed under GPLv2 or later, see file LICENSE in this source tree. 1.76 ++ */ 1.77 ++ 1.78 ++#define PACKED __attribute__ ((packed)) 1.79 ++#define ALWAYS_INLINE inline 1.80 ++#define speed_inline 1.81 ++#define size_inline ALWAYS_INLINE 1.82 ++ 1.83 ++ 1.84 ++typedef struct { 1.85 ++ uint8_t *ptr; 1.86 ++ 1.87 ++ uint32_t code; 1.88 ++ uint32_t range; 1.89 ++ uint32_t bound; 1.90 ++} rc_t; 1.91 ++ 1.92 ++#define RC_TOP_BITS 24 1.93 ++#define RC_MOVE_BITS 5 1.94 ++#define RC_MODEL_TOTAL_BITS 11 1.95 ++ 1.96 ++/* Called twice, but one callsite is in speed_inline'd rc_is_bit_1() */ 1.97 ++static void rc_do_normalize(rc_t *rc) 1.98 ++{ 1.99 ++ rc->range <<= 8; 1.100 ++ rc->code = (rc->code << 8) | *rc->ptr++; 1.101 ++} 1.102 ++ 1.103 ++static ALWAYS_INLINE void rc_normalize(rc_t *rc) 1.104 ++{ 1.105 ++ if (rc->range < (1 << RC_TOP_BITS)) { 1.106 ++ rc_do_normalize(rc); 1.107 ++ } 1.108 ++} 1.109 ++ 1.110 ++/* Called once */ 1.111 ++static void rc_init(rc_t *rc) /*, int buffer_size) */ 1.112 ++{ 1.113 ++ int i; 1.114 ++ 1.115 ++ rc->range = 0; 1.116 ++ for (i = 0; i < 5; i++) { 1.117 ++ rc_do_normalize(rc); 1.118 ++ } 1.119 ++ rc->range = 0xffffffff; 1.120 ++} 1.121 ++ 1.122 ++/* rc_is_bit_1 is called 9 times */ 1.123 ++static speed_inline int rc_is_bit_1(rc_t *rc, uint16_t *p) 1.124 ++{ 1.125 ++ rc_normalize(rc); 1.126 ++ rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS); 1.127 ++ if (rc->code < rc->bound) { 1.128 ++ rc->range = rc->bound; 1.129 ++ *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS; 1.130 ++ return 0; 1.131 ++ } 1.132 ++ rc->range -= rc->bound; 1.133 ++ rc->code -= rc->bound; 1.134 ++ *p -= *p >> RC_MOVE_BITS; 1.135 ++ return 1; 1.136 ++} 1.137 ++ 1.138 ++/* Called 4 times in unlzma loop */ 1.139 ++static ALWAYS_INLINE int rc_get_bit(rc_t *rc, uint16_t *p, int *symbol) 1.140 ++{ 1.141 ++ int ret = rc_is_bit_1(rc, p); 1.142 ++ *symbol = *symbol * 2 + ret; 1.143 ++ return ret; 1.144 ++} 1.145 ++ 1.146 ++/* Called once */ 1.147 ++static ALWAYS_INLINE int rc_direct_bit(rc_t *rc) 1.148 ++{ 1.149 ++ rc_normalize(rc); 1.150 ++ rc->range >>= 1; 1.151 ++ if (rc->code >= rc->range) { 1.152 ++ rc->code -= rc->range; 1.153 ++ return 1; 1.154 ++ } 1.155 ++ return 0; 1.156 ++} 1.157 ++ 1.158 ++/* Called twice */ 1.159 ++static speed_inline void 1.160 ++rc_bit_tree_decode(rc_t *rc, uint16_t *p, int num_levels, int *symbol) 1.161 ++{ 1.162 ++ int i = num_levels; 1.163 ++ 1.164 ++ *symbol = 1; 1.165 ++ while (i--) 1.166 ++ rc_get_bit(rc, p + *symbol, symbol); 1.167 ++ *symbol -= 1 << num_levels; 1.168 ++} 1.169 ++ 1.170 ++ 1.171 ++typedef struct { 1.172 ++ uint8_t pos; 1.173 ++ uint32_t dict_size; 1.174 ++ uint64_t dst_size; 1.175 ++} PACKED lzma_header_t; 1.176 ++ 1.177 ++ 1.178 ++/* #defines will force compiler to compute/optimize each one with each usage. 1.179 ++ * Have heart and use enum instead. */ 1.180 ++enum { 1.181 ++ LZMA_BASE_SIZE = 1846, 1.182 ++ LZMA_LIT_SIZE = 768, 1.183 ++ 1.184 ++ LZMA_NUM_POS_BITS_MAX = 4, 1.185 ++ 1.186 ++ LZMA_LEN_NUM_LOW_BITS = 3, 1.187 ++ LZMA_LEN_NUM_MID_BITS = 3, 1.188 ++ LZMA_LEN_NUM_HIGH_BITS = 8, 1.189 ++ 1.190 ++ LZMA_LEN_CHOICE = 0, 1.191 ++ LZMA_LEN_CHOICE_2 = (LZMA_LEN_CHOICE + 1), 1.192 ++ LZMA_LEN_LOW = (LZMA_LEN_CHOICE_2 + 1), 1.193 ++ LZMA_LEN_MID = (LZMA_LEN_LOW \ 1.194 ++ + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))), 1.195 ++ LZMA_LEN_HIGH = (LZMA_LEN_MID \ 1.196 ++ + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))), 1.197 ++ LZMA_NUM_LEN_PROBS = (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)), 1.198 ++ 1.199 ++ LZMA_NUM_STATES = 12, 1.200 ++ LZMA_NUM_LIT_STATES = 7, 1.201 ++ 1.202 ++ LZMA_START_POS_MODEL_INDEX = 4, 1.203 ++ LZMA_END_POS_MODEL_INDEX = 14, 1.204 ++ LZMA_NUM_FULL_DISTANCES = (1 << (LZMA_END_POS_MODEL_INDEX >> 1)), 1.205 ++ 1.206 ++ LZMA_NUM_POS_SLOT_BITS = 6, 1.207 ++ LZMA_NUM_LEN_TO_POS_STATES = 4, 1.208 ++ 1.209 ++ LZMA_NUM_ALIGN_BITS = 4, 1.210 ++ 1.211 ++ LZMA_MATCH_MIN_LEN = 2, 1.212 ++ 1.213 ++ LZMA_IS_MATCH = 0, 1.214 ++ LZMA_IS_REP = (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)), 1.215 ++ LZMA_IS_REP_G0 = (LZMA_IS_REP + LZMA_NUM_STATES), 1.216 ++ LZMA_IS_REP_G1 = (LZMA_IS_REP_G0 + LZMA_NUM_STATES), 1.217 ++ LZMA_IS_REP_G2 = (LZMA_IS_REP_G1 + LZMA_NUM_STATES), 1.218 ++ LZMA_IS_REP_0_LONG = (LZMA_IS_REP_G2 + LZMA_NUM_STATES), 1.219 ++ LZMA_POS_SLOT = (LZMA_IS_REP_0_LONG \ 1.220 ++ + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)), 1.221 ++ LZMA_SPEC_POS = (LZMA_POS_SLOT \ 1.222 ++ + (LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)), 1.223 ++ LZMA_ALIGN = (LZMA_SPEC_POS \ 1.224 ++ + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX), 1.225 ++ LZMA_LEN_CODER = (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)), 1.226 ++ LZMA_REP_LEN_CODER = (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS), 1.227 ++ LZMA_LITERAL = (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS), 1.228 ++}; 1.229 ++ 1.230 ++ 1.231 ++void unlzma(char *from, char *to, char *heap) 1.232 ++{ 1.233 ++ lzma_header_t header; 1.234 ++ int lc, pb, lp; 1.235 ++ uint32_t pos_state_mask; 1.236 ++ uint32_t literal_pos_mask; 1.237 ++ uint16_t *p; 1.238 ++ rc_t *rc = (rc_t *) heap; 1.239 ++ int i; 1.240 ++ uint8_t *buffer = (void *) to; 1.241 ++ uint8_t previous_byte = 0; 1.242 ++ size_t buffer_pos = 0; 1.243 ++ int len = 0; 1.244 ++ int state = 0; 1.245 ++ uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; 1.246 ++ 1.247 ++ memcpy(&header, from, sizeof(header)); 1.248 ++ from += sizeof(header); 1.249 ++ heap += sizeof(*rc); 1.250 ++ rc->ptr = (void *) from; 1.251 ++ 1.252 ++ i = header.pos / 9; 1.253 ++ lc = header.pos % 9; 1.254 ++ pb = i / 5; 1.255 ++ lp = i % 5; 1.256 ++ pos_state_mask = (1 << pb) - 1; 1.257 ++ literal_pos_mask = (1 << lp) - 1; 1.258 ++ 1.259 ++ /* Example values from linux-3.3.4.tar.lzma: 1.260 ++ * dict_size: 64M, dst_size: 2^64-1 1.261 ++ */ 1.262 ++ header.dict_size = SWAP_LE32(header.dict_size); 1.263 ++ header.dst_size = SWAP_LE64(header.dst_size); 1.264 ++ 1.265 ++ //if (header.dict_size == 0) 1.266 ++ // header.dict_size++; 1.267 ++ 1.268 ++ rc_init(rc); 1.269 ++ 1.270 ++ { 1.271 ++ int num_probs; 1.272 ++ 1.273 ++ num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)); 1.274 ++ //p = xmalloc(num_probs * sizeof(*p)); 1.275 ++ p = (void *) heap; 1.276 ++ num_probs += LZMA_LITERAL - LZMA_BASE_SIZE; 1.277 ++ for (i = 0; i < num_probs; i++) 1.278 ++ p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; 1.279 ++ } 1.280 ++ 1.281 ++ 1.282 ++ while (buffer_pos < header.dst_size) { 1.283 ++ int pos_state = buffer_pos & pos_state_mask; 1.284 ++ uint16_t *prob = p + LZMA_IS_MATCH + (state << LZMA_NUM_POS_BITS_MAX) + pos_state; 1.285 ++ 1.286 ++ if (!rc_is_bit_1(rc, prob)) { 1.287 ++ static const char next_state[LZMA_NUM_STATES] = 1.288 ++ { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 }; 1.289 ++ int mi = 1; 1.290 ++ 1.291 ++ prob = (p + LZMA_LITERAL 1.292 ++ + (LZMA_LIT_SIZE * (((buffer_pos & literal_pos_mask) << lc) 1.293 ++ + (previous_byte >> (8 - lc)) 1.294 ++ ) 1.295 ++ ) 1.296 ++ ); 1.297 ++ 1.298 ++ if (state >= LZMA_NUM_LIT_STATES) { 1.299 ++ int match_byte; 1.300 ++ uint32_t pos = buffer_pos - rep0; 1.301 ++ 1.302 ++ while (pos >= header.dict_size) 1.303 ++ pos += header.dict_size; 1.304 ++ match_byte = buffer[pos]; 1.305 ++ do { 1.306 ++ int bit; 1.307 ++ 1.308 ++ match_byte <<= 1; 1.309 ++ bit = match_byte & 0x100; 1.310 ++ bit ^= (rc_get_bit(rc, prob + 0x100 + bit + mi, &mi) << 8); /* 0x100 or 0 */ 1.311 ++ if (bit) 1.312 ++ break; 1.313 ++ } while (mi < 0x100); 1.314 ++ } 1.315 ++ while (mi < 0x100) { 1.316 ++ rc_get_bit(rc, prob + mi, &mi); 1.317 ++ } 1.318 ++ 1.319 ++ state = next_state[state]; 1.320 ++ 1.321 ++ previous_byte = (uint8_t) mi; 1.322 ++ len = 1; 1.323 ++ goto one_byte2; 1.324 ++ } else { 1.325 ++ int num_bits; 1.326 ++ int offset; 1.327 ++ uint16_t *prob2; 1.328 ++#define prob_len prob2 1.329 ++ 1.330 ++ prob2 = p + LZMA_IS_REP + state; 1.331 ++ if (!rc_is_bit_1(rc, prob2)) { 1.332 ++ rep3 = rep2; 1.333 ++ rep2 = rep1; 1.334 ++ rep1 = rep0; 1.335 ++ state = state < LZMA_NUM_LIT_STATES ? 0 : 3; 1.336 ++ prob2 = p + LZMA_LEN_CODER; 1.337 ++ } else { 1.338 ++ prob2 += LZMA_IS_REP_G0 - LZMA_IS_REP; 1.339 ++ if (!rc_is_bit_1(rc, prob2)) { 1.340 ++ prob2 = (p + LZMA_IS_REP_0_LONG 1.341 ++ + (state << LZMA_NUM_POS_BITS_MAX) 1.342 ++ + pos_state 1.343 ++ ); 1.344 ++ if (!rc_is_bit_1(rc, prob2)) { 1.345 ++ state = state < LZMA_NUM_LIT_STATES ? 9 : 11; 1.346 ++ len = 1; 1.347 ++ goto string; 1.348 ++ } 1.349 ++ } else { 1.350 ++ uint32_t distance; 1.351 ++ 1.352 ++ prob2 += LZMA_IS_REP_G1 - LZMA_IS_REP_G0; 1.353 ++ distance = rep1; 1.354 ++ if (rc_is_bit_1(rc, prob2)) { 1.355 ++ prob2 += LZMA_IS_REP_G2 - LZMA_IS_REP_G1; 1.356 ++ distance = rep2; 1.357 ++ if (rc_is_bit_1(rc, prob2)) { 1.358 ++ distance = rep3; 1.359 ++ rep3 = rep2; 1.360 ++ } 1.361 ++ rep2 = rep1; 1.362 ++ } 1.363 ++ rep1 = rep0; 1.364 ++ rep0 = distance; 1.365 ++ } 1.366 ++ state = state < LZMA_NUM_LIT_STATES ? 8 : 11; 1.367 ++ prob2 = p + LZMA_REP_LEN_CODER; 1.368 ++ } 1.369 ++ 1.370 ++ prob_len = prob2 + LZMA_LEN_CHOICE; 1.371 ++ num_bits = LZMA_LEN_NUM_LOW_BITS; 1.372 ++ if (!rc_is_bit_1(rc, prob_len)) { 1.373 ++ prob_len += LZMA_LEN_LOW - LZMA_LEN_CHOICE 1.374 ++ + (pos_state << LZMA_LEN_NUM_LOW_BITS); 1.375 ++ offset = 0; 1.376 ++ } else { 1.377 ++ prob_len += LZMA_LEN_CHOICE_2 - LZMA_LEN_CHOICE; 1.378 ++ if (!rc_is_bit_1(rc, prob_len)) { 1.379 ++ prob_len += LZMA_LEN_MID - LZMA_LEN_CHOICE_2 1.380 ++ + (pos_state << LZMA_LEN_NUM_MID_BITS); 1.381 ++ offset = 1 << LZMA_LEN_NUM_LOW_BITS; 1.382 ++ num_bits += LZMA_LEN_NUM_MID_BITS - LZMA_LEN_NUM_LOW_BITS; 1.383 ++ } else { 1.384 ++ prob_len += LZMA_LEN_HIGH - LZMA_LEN_CHOICE_2; 1.385 ++ offset = ((1 << LZMA_LEN_NUM_LOW_BITS) 1.386 ++ + (1 << LZMA_LEN_NUM_MID_BITS)); 1.387 ++ num_bits += LZMA_LEN_NUM_HIGH_BITS - LZMA_LEN_NUM_LOW_BITS; 1.388 ++ } 1.389 ++ } 1.390 ++ rc_bit_tree_decode(rc, prob_len, num_bits, &len); 1.391 ++ len += offset; 1.392 ++ 1.393 ++ if (state < 4) { 1.394 ++ int pos_slot; 1.395 ++ uint16_t *prob3; 1.396 ++ 1.397 ++ state += LZMA_NUM_LIT_STATES; 1.398 ++ prob3 = p + LZMA_POS_SLOT + 1.399 ++ ((len < LZMA_NUM_LEN_TO_POS_STATES ? len : 1.400 ++ LZMA_NUM_LEN_TO_POS_STATES - 1) 1.401 ++ << LZMA_NUM_POS_SLOT_BITS); 1.402 ++ rc_bit_tree_decode(rc, prob3, 1.403 ++ LZMA_NUM_POS_SLOT_BITS, &pos_slot); 1.404 ++ rep0 = pos_slot; 1.405 ++ if (pos_slot >= LZMA_START_POS_MODEL_INDEX) { 1.406 ++ int i2, mi2, num_bits2 = (pos_slot >> 1) - 1; 1.407 ++ rep0 = 2 | (pos_slot & 1); 1.408 ++ if (pos_slot < LZMA_END_POS_MODEL_INDEX) { 1.409 ++ rep0 <<= num_bits2; 1.410 ++ prob3 = p + LZMA_SPEC_POS + rep0 - pos_slot - 1; 1.411 ++ } else { 1.412 ++ for (; num_bits2 != LZMA_NUM_ALIGN_BITS; num_bits2--) 1.413 ++ rep0 = (rep0 << 1) | rc_direct_bit(rc); 1.414 ++ rep0 <<= LZMA_NUM_ALIGN_BITS; 1.415 ++ prob3 = p + LZMA_ALIGN; 1.416 ++ } 1.417 ++ i2 = 1; 1.418 ++ mi2 = 1; 1.419 ++ while (num_bits2--) { 1.420 ++ if (rc_get_bit(rc, prob3 + mi2, &mi2)) 1.421 ++ rep0 |= i2; 1.422 ++ i2 <<= 1; 1.423 ++ } 1.424 ++ } 1.425 ++ if (++rep0 == 0) 1.426 ++ break; 1.427 ++ } 1.428 ++ 1.429 ++ len += LZMA_MATCH_MIN_LEN; 1.430 ++ string: 1.431 ++ do { 1.432 ++ uint32_t pos = buffer_pos - rep0; 1.433 ++ while (pos >= header.dict_size) 1.434 ++ pos += header.dict_size; 1.435 ++ previous_byte = buffer[pos]; 1.436 ++ one_byte2: 1.437 ++ buffer[buffer_pos++] = previous_byte; 1.438 ++ len--; 1.439 ++ } while (len != 0 && buffer_pos < header.dst_size); 1.440 ++ } 1.441 ++ } 1.442 ++} 1.443 +--- /dev/null 1.444 ++++ core/unlz4.c 1.445 +@@ -0,0 +1,112 @@ 1.446 ++/* 1.447 ++ * Copyright (C) 2015, pascal.bellard@slitaz.org 1.448 ++ * 1.449 ++ * This program is free software; you can redistribute it and/or modify 1.450 ++ * it under the terms of the GNU General Public License version 2 as 1.451 ++ * published by the Free Software Foundation. 1.452 ++ */ 1.453 ++ 1.454 ++#define LZ4_MAGIC 0x184D2204 /* Spec 1.5.0 */ 1.455 ++#define LZ4_LEGACY 0x184C2102 1.456 ++#define LZ4_SKIP(n) ((((n) - 0x184D2A50) >> 4) == 0) 1.457 ++ 1.458 ++static unsigned lz4cnt(unsigned char **p, unsigned n) 1.459 ++{ 1.460 ++ int i; 1.461 ++ 1.462 ++ if (n == 0xF) do { 1.463 ++ i = *(*p)++; 1.464 ++ n += i; 1.465 ++ } while (i == 0xFF); 1.466 ++ return n; 1.467 ++} 1.468 ++ 1.469 ++char *unlz4(unsigned char *from, unsigned char *end) 1.470 ++{ 1.471 ++ unsigned char *p, *end_chunk, *to, flags, mask; 1.472 ++ long magic; 1.473 ++ unsigned i, n, size; 1.474 ++ 1.475 ++ for (p = from, flags = size = 0; p < end;) { 1.476 ++ while (1) { 1.477 ++ magic = * (long *) p; 1.478 ++ p += sizeof(long); 1.479 ++ if (magic == LZ4_LEGACY) continue; 1.480 ++ if (magic != LZ4_MAGIC) break; 1.481 ++ flags = *p; 1.482 ++ if (flags & 8) { 1.483 ++ size = * (unsigned *) (p + 2); 1.484 ++ goto sizefound; 1.485 ++ } 1.486 ++ p += 3; /* skip FLG BD HC */ 1.487 ++ } 1.488 ++ if (LZ4_SKIP(magic)) { 1.489 ++ p += 4 + * (long *) p; 1.490 ++ continue; 1.491 ++ } 1.492 ++ mask = 4; /* Content checksum */ 1.493 ++ if (magic) { 1.494 ++ if (magic > 0) 1.495 ++ for (end_chunk = p + magic; p < end_chunk;) { 1.496 ++ unsigned char token = *p++; 1.497 ++ 1.498 ++ n = lz4cnt(&p, token >> 4); 1.499 ++ size += n; 1.500 ++ p += n; 1.501 ++ if (p >= end_chunk) break; 1.502 ++ p += sizeof(unsigned short); 1.503 ++ size += 4 + lz4cnt(&p, token & 0xF); 1.504 ++ } 1.505 ++ else { 1.506 ++ magic &= 0x7FffFFff; 1.507 ++ p += magic; 1.508 ++ size += magic; 1.509 ++ } 1.510 ++ mask = 0x10; /* Block checksum */ 1.511 ++ } 1.512 ++ if (flags & mask) p += 4; /* skip block checksum */ 1.513 ++ } 1.514 ++sizefound: 1.515 ++ size += 16 - (p - from); 1.516 ++ memmove(from + size, from, p - from); 1.517 ++ for (to = from, p = from += size, end += size, flags = 0; p < end;) { 1.518 ++ while (1) { 1.519 ++ magic = * (long *) p; 1.520 ++ p += sizeof(long); 1.521 ++ if (magic == LZ4_LEGACY) continue; 1.522 ++ if (magic != LZ4_MAGIC) break; 1.523 ++ flags = *p; 1.524 ++ if (flags & 8) p += 8; /* skip size */ 1.525 ++ p += 3; /* skip FLG BD HC */ 1.526 ++ } 1.527 ++ if (LZ4_SKIP(magic)) { 1.528 ++ p += 4 + * (long *) p; 1.529 ++ continue; 1.530 ++ } 1.531 ++ mask = 4; /* Content checksum */ 1.532 ++ if (magic) { 1.533 ++ if (magic > 0) 1.534 ++ for (end_chunk = p + magic; p < end_chunk;) { 1.535 ++ char *dico; 1.536 ++ unsigned char token = *p++; 1.537 ++ 1.538 ++ n = lz4cnt(&p, token >> 4); 1.539 ++ for (i = 0; i < n; i++) 1.540 ++ *to++ = *p++; 1.541 ++ if (p >= end_chunk) break; 1.542 ++ dico = to - (* (unsigned short *) p); 1.543 ++ p += sizeof(unsigned short); 1.544 ++ n = 4 + lz4cnt(&p, token & 0xF); 1.545 ++ for (i = 0; i < n; i++) 1.546 ++ *to++ = *dico++; 1.547 ++ } 1.548 ++ else for (end_chunk = p + (magic & 0x7FffFFff); 1.549 ++ p < end_chunk;) { 1.550 ++ *to++ = *p++; 1.551 ++ } 1.552 ++ mask = 0x10; /* Block checksum */ 1.553 ++ } 1.554 ++ if (flags & mask) p += 4; /* Skip checksum */ 1.555 ++ } 1.556 ++ return to; 1.557 ++}