forked from xuos/xiuos
First commit XiUOS
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
SRC_FILES := blocksort.c bzlib.c compress.c huffman.c
|
||||
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,838 @@
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "bzlib_private.h"
|
||||
|
||||
#define MSWAP(zz1, zz2) { \
|
||||
int32_t zztmp = zz1; \
|
||||
zz1 = zz2; \
|
||||
zz2 = zztmp; \
|
||||
}
|
||||
|
||||
static void mvswap(uint32_t* ptr, int32_t zzp1, int32_t zzp2, int32_t zzn)
|
||||
{
|
||||
while (zzn > 0) {
|
||||
MSWAP(ptr[zzp1], ptr[zzp2]);
|
||||
zzp1++;
|
||||
zzp2++;
|
||||
zzn--;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int32_t mmin(int32_t a, int32_t b)
|
||||
{
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
static inline void FallbackSimpleSort(uint32_t* fmap,
|
||||
uint32_t* eclass,
|
||||
int32_t lo,
|
||||
int32_t hi)
|
||||
{
|
||||
int32_t i, j, tmp;
|
||||
uint32_t ec_tmp;
|
||||
|
||||
if (lo == hi) return;
|
||||
|
||||
if (hi - lo > 3) {
|
||||
for (i = hi-4; i >= lo; i--) {
|
||||
tmp = fmap[i];
|
||||
ec_tmp = eclass[tmp];
|
||||
for (j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4)
|
||||
fmap[j-4] = fmap[j];
|
||||
fmap[j-4] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = hi-1; i >= lo; i--) {
|
||||
tmp = fmap[i];
|
||||
ec_tmp = eclass[tmp];
|
||||
for (j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++)
|
||||
fmap[j-1] = fmap[j];
|
||||
fmap[j-1] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define FPUSH(lz,hz) { \
|
||||
stackLo[sp] = lz; \
|
||||
stackHi[sp] = hz; \
|
||||
sp++; \
|
||||
}
|
||||
|
||||
#define FPOP(lz,hz) { \
|
||||
sp--; \
|
||||
lz = stackLo[sp]; \
|
||||
hz = stackHi[sp]; \
|
||||
}
|
||||
|
||||
#define FALLBACK_QSORT_SMALL_THRESH 10
|
||||
#define FALLBACK_QSORT_STACK_SIZE 100
|
||||
|
||||
static void FallbackQSort3(uint32_t* fmap,
|
||||
uint32_t* eclass,
|
||||
int32_t loSt,
|
||||
int32_t hiSt)
|
||||
{
|
||||
int32_t sp;
|
||||
uint32_t r;
|
||||
int32_t stackLo[FALLBACK_QSORT_STACK_SIZE];
|
||||
int32_t stackHi[FALLBACK_QSORT_STACK_SIZE];
|
||||
|
||||
r = 0;
|
||||
|
||||
sp = 0;
|
||||
FPUSH(loSt, hiSt);
|
||||
|
||||
while (sp > 0) {
|
||||
int32_t unLo, unHi, ltLo, gtHi, n, m;
|
||||
int32_t lo, hi;
|
||||
uint32_t med;
|
||||
uint32_t r3;
|
||||
|
||||
ASSERTH(sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004);
|
||||
|
||||
FPOP(lo, hi);
|
||||
if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
|
||||
FallbackSimpleSort(fmap, eclass, lo, hi);
|
||||
continue;
|
||||
}
|
||||
|
||||
r = ((r * 7621) + 1) % 32768;
|
||||
r3 = r % 3;
|
||||
if (r3 == 0)
|
||||
med = eclass[fmap[lo]];
|
||||
else if (r3 == 1)
|
||||
med = eclass[fmap[(lo+hi)>>1]];
|
||||
else
|
||||
med = eclass[fmap[hi]];
|
||||
|
||||
unLo = ltLo = lo;
|
||||
unHi = gtHi = hi;
|
||||
|
||||
while (1) {
|
||||
while (1) {
|
||||
if (unLo > unHi) break;
|
||||
n = (int32_t)eclass[fmap[unLo]] - (int32_t)med;
|
||||
if (n == 0) {
|
||||
MSWAP(fmap[unLo], fmap[ltLo]);
|
||||
ltLo++;
|
||||
unLo++;
|
||||
continue;
|
||||
}
|
||||
if (n > 0) break;
|
||||
unLo++;
|
||||
}
|
||||
while (1) {
|
||||
if (unLo > unHi) break;
|
||||
n = (int32_t)eclass[fmap[unHi]] - (int32_t)med;
|
||||
if (n == 0) {
|
||||
MSWAP(fmap[unHi], fmap[gtHi]);
|
||||
gtHi--; unHi--;
|
||||
continue;
|
||||
}
|
||||
if (n < 0) break;
|
||||
unHi--;
|
||||
}
|
||||
if (unLo > unHi) break;
|
||||
MSWAP(fmap[unLo], fmap[unHi]); unLo++; unHi--;
|
||||
}
|
||||
|
||||
ASSERTD(unHi == unLo-1, "fallbackQSort3(2)");
|
||||
|
||||
if (gtHi < ltLo) continue;
|
||||
|
||||
n = mmin(ltLo-lo, unLo-ltLo); mvswap(fmap, lo, unLo-n, n);
|
||||
m = mmin(hi-gtHi, gtHi-unHi); mvswap(fmap, unLo, hi-m+1, m);
|
||||
|
||||
n = lo + unLo - ltLo - 1;
|
||||
m = hi - (gtHi - unHi) + 1;
|
||||
|
||||
if (n - lo > hi - m) {
|
||||
FPUSH(lo, n);
|
||||
FPUSH(m, hi);
|
||||
} else {
|
||||
FPUSH(m, hi);
|
||||
FPUSH(lo, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef FPUSH
|
||||
#undef FPOP
|
||||
#undef FALLBACK_QSORT_SMALL_THRESH
|
||||
#undef FALLBACK_QSORT_STACK_SIZE
|
||||
|
||||
|
||||
#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
|
||||
#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
|
||||
#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
|
||||
#define WORD_BH(zz) bhtab[(zz) >> 5]
|
||||
#define UNALIGNED_BH(zz) ((zz) & 0x01f)
|
||||
|
||||
static void FallbackSort(EState* state)
|
||||
{
|
||||
int32_t ftab[257];
|
||||
int32_t ftabCopy[256];
|
||||
int32_t H, i, j, k, l, r, cc, cc1;
|
||||
int32_t nNotDone;
|
||||
int32_t nBhtab;
|
||||
|
||||
uint32_t *const fmap = state->arr1;
|
||||
uint32_t *const eclass = state->arr2;
|
||||
#define ECLASS8 ((uint8_t*)eclass)
|
||||
uint32_t *const bhtab = state->ftab;
|
||||
const int32_t nblock = state->nblock;
|
||||
|
||||
|
||||
for (i = 0; i < 257; i++) ftab[i] = 0;
|
||||
for (i = 0; i < nblock; i++) ftab[ECLASS8[i]]++;
|
||||
for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
|
||||
|
||||
j = ftab[0];
|
||||
for (i = 1; i < 257; i++) {
|
||||
j += ftab[i];
|
||||
ftab[i] = j;
|
||||
}
|
||||
|
||||
for (i = 0; i < nblock; i++) {
|
||||
j = ECLASS8[i];
|
||||
k = ftab[j] - 1;
|
||||
ftab[j] = k;
|
||||
fmap[k] = i;
|
||||
}
|
||||
|
||||
nBhtab = 2 + ((uint32_t)nblock / 32);
|
||||
for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
|
||||
for (i = 0; i < 256; i++) SET_BH(ftab[i]);
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
SET_BH(nblock + 2*i);
|
||||
CLEAR_BH(nblock + 2*i + 1);
|
||||
}
|
||||
|
||||
H = 1;
|
||||
while (1) {
|
||||
j = 0;
|
||||
for (i = 0; i < nblock; i++) {
|
||||
if (ISSET_BH(i))
|
||||
j = i;
|
||||
k = fmap[i] - H;
|
||||
if (k < 0)
|
||||
k += nblock;
|
||||
eclass[k] = j;
|
||||
}
|
||||
|
||||
nNotDone = 0;
|
||||
r = -1;
|
||||
while (1) {
|
||||
|
||||
k = r + 1;
|
||||
while (ISSET_BH(k) && UNALIGNED_BH(k))
|
||||
k++;
|
||||
if (ISSET_BH(k)) {
|
||||
while (WORD_BH(k) == 0xffffffff) k += 32;
|
||||
while (ISSET_BH(k)) k++;
|
||||
}
|
||||
l = k - 1;
|
||||
if (l >= nblock)
|
||||
break;
|
||||
while (!ISSET_BH(k) && UNALIGNED_BH(k))
|
||||
k++;
|
||||
if (!ISSET_BH(k)) {
|
||||
while (WORD_BH(k) == 0x00000000) k += 32;
|
||||
while (!ISSET_BH(k)) k++;
|
||||
}
|
||||
r = k - 1;
|
||||
if (r >= nblock)
|
||||
break;
|
||||
|
||||
if (r > l) {
|
||||
nNotDone += (r - l + 1);
|
||||
FallbackQSort3(fmap, eclass, l, r);
|
||||
|
||||
cc = -1;
|
||||
for (i = l; i <= r; i++) {
|
||||
cc1 = eclass[fmap[i]];
|
||||
if (cc != cc1) {
|
||||
SET_BH(i);
|
||||
cc = cc1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
H *= 2;
|
||||
if (H > nblock || nNotDone == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < nblock; i++) {
|
||||
while (ftabCopy[j] == 0)
|
||||
j++;
|
||||
ftabCopy[j]--;
|
||||
ECLASS8[fmap[i]] = (uint8_t)j;
|
||||
}
|
||||
ASSERTH(j < 256, 1005);
|
||||
#undef ECLASS8
|
||||
}
|
||||
|
||||
#undef SET_BH
|
||||
#undef CLEAR_BH
|
||||
#undef ISSET_BH
|
||||
#undef WORD_BH
|
||||
#undef UNALIGNED_BH
|
||||
|
||||
static int MainGtU(EState* state,
|
||||
uint32_t i1,
|
||||
uint32_t i2)
|
||||
{
|
||||
int32_t k;
|
||||
uint8_t c1, c2;
|
||||
uint16_t s1, s2;
|
||||
|
||||
uint8_t *const block = state->block;
|
||||
uint16_t *const quadrant = state->quadrant;
|
||||
const int32_t nblock = state->nblock;
|
||||
|
||||
|
||||
#if BZIP2_SPEED >= 1
|
||||
|
||||
#define TIMES_8(code) \
|
||||
code; code; code; code; \
|
||||
code; code; code; code;
|
||||
#define TIMES_12(code) \
|
||||
code; code; code; code; \
|
||||
code; code; code; code; \
|
||||
code; code; code; code;
|
||||
|
||||
#else
|
||||
|
||||
#define TIMES_8(code) { \
|
||||
int nn = 8; \
|
||||
do { \
|
||||
code; \
|
||||
} while (--nn); \
|
||||
}
|
||||
#define TIMES_12(code) { \
|
||||
int nn = 12; \
|
||||
do { \
|
||||
code; \
|
||||
} while (--nn); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ASSERTD(i1 != i2, "mainGtU");
|
||||
TIMES_12(
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
i1++; i2++;
|
||||
)
|
||||
|
||||
k = nblock + 8;
|
||||
|
||||
do {
|
||||
TIMES_8(
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
s1 = quadrant[i1]; s2 = quadrant[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1++; i2++;
|
||||
)
|
||||
|
||||
if (i1 >= nblock) i1 -= nblock;
|
||||
if (i2 >= nblock) i2 -= nblock;
|
||||
|
||||
state->budget--;
|
||||
k -= 8;
|
||||
} while (k >= 0);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#undef TIMES_8
|
||||
#undef TIMES_12
|
||||
|
||||
static
|
||||
const uint32_t incs[14] = {
|
||||
1, 4, 13, 40, 121, 364, 1093, 3280,
|
||||
9841, 29524, 88573, 265720,
|
||||
797161, 2391484
|
||||
};
|
||||
|
||||
static void MainSimpleSort(EState* state,
|
||||
int32_t lo,
|
||||
int32_t hi,
|
||||
int32_t d)
|
||||
{
|
||||
uint32_t *const ptr = state->ptr;
|
||||
|
||||
int hp = 0;
|
||||
{
|
||||
int bigN = hi - lo;
|
||||
if (bigN <= 0)
|
||||
return;
|
||||
while (incs[hp] <= bigN)
|
||||
hp++;
|
||||
hp--;
|
||||
}
|
||||
|
||||
for (; hp >= 0; hp--) {
|
||||
int32_t i;
|
||||
unsigned h;
|
||||
|
||||
h = incs[hp];
|
||||
i = lo + h;
|
||||
while (1) {
|
||||
unsigned j;
|
||||
unsigned v;
|
||||
|
||||
if (i > hi) break;
|
||||
v = ptr[i];
|
||||
j = i;
|
||||
while (MainGtU(state, ptr[j-h]+d, v+d)) {
|
||||
ptr[j] = ptr[j-h];
|
||||
j = j - h;
|
||||
if (j <= (lo + h - 1)) break;
|
||||
}
|
||||
ptr[j] = v;
|
||||
i++;
|
||||
|
||||
#if BZIP2_SPEED >= 3
|
||||
if (i > hi) break;
|
||||
v = ptr[i];
|
||||
j = i;
|
||||
while (MainGtU(state, ptr[j-h]+d, v+d)) {
|
||||
ptr[j] = ptr[j-h];
|
||||
j = j - h;
|
||||
if (j <= (lo + h - 1)) break;
|
||||
}
|
||||
ptr[j] = v;
|
||||
i++;
|
||||
if (i > hi) break;
|
||||
v = ptr[i];
|
||||
j = i;
|
||||
while (MainGtU(state, ptr[j-h]+d, v+d)) {
|
||||
ptr[j] = ptr[j-h];
|
||||
j = j - h;
|
||||
if (j <= (lo + h - 1)) break;
|
||||
}
|
||||
ptr[j] = v;
|
||||
i++;
|
||||
#endif
|
||||
if (state->budget < 0) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline uint8_t mmed3(uint8_t a, uint8_t b, uint8_t c)
|
||||
{
|
||||
uint8_t t;
|
||||
if (a > b) {
|
||||
t = a;
|
||||
a = b;
|
||||
b = t;
|
||||
}
|
||||
if (b > c) {
|
||||
b = c;
|
||||
if (a > b)
|
||||
b = a;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
#define MPUSH(lz,hz,dz) { \
|
||||
stackLo[sp] = lz; \
|
||||
stackHi[sp] = hz; \
|
||||
stackD [sp] = dz; \
|
||||
sp++; \
|
||||
}
|
||||
|
||||
#define MPOP(lz,hz,dz) { \
|
||||
sp--; \
|
||||
lz = stackLo[sp]; \
|
||||
hz = stackHi[sp]; \
|
||||
dz = stackD [sp]; \
|
||||
}
|
||||
|
||||
#define MNEXTSIZE(az) (nextHi[az] - nextLo[az])
|
||||
|
||||
#define MNEXTSWAP(az,bz) { \
|
||||
int32_t tz; \
|
||||
tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
|
||||
tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
|
||||
tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; \
|
||||
}
|
||||
|
||||
#define MAIN_QSORT_SMALL_THRESH 20
|
||||
#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
|
||||
#define MAIN_QSORT_STACK_SIZE 100
|
||||
|
||||
static void MainQSort3(EState* state,
|
||||
int32_t loSt,
|
||||
int32_t hiSt
|
||||
)
|
||||
{
|
||||
enum { dSt = BZ_N_RADIX };
|
||||
int32_t unLo, unHi, ltLo, gtHi, n, m, med;
|
||||
int32_t sp, lo, hi, d;
|
||||
|
||||
int32_t stackLo[MAIN_QSORT_STACK_SIZE];
|
||||
int32_t stackHi[MAIN_QSORT_STACK_SIZE];
|
||||
int32_t stackD [MAIN_QSORT_STACK_SIZE];
|
||||
|
||||
int32_t nextLo[3];
|
||||
int32_t nextHi[3];
|
||||
int32_t nextD [3];
|
||||
|
||||
uint32_t *const ptr = state->ptr;
|
||||
uint8_t *const block = state->block;
|
||||
|
||||
sp = 0;
|
||||
MPUSH(loSt, hiSt, dSt);
|
||||
|
||||
while (sp > 0) {
|
||||
ASSERTH(sp < MAIN_QSORT_STACK_SIZE - 2, 1001);
|
||||
|
||||
MPOP(lo, hi, d);
|
||||
if (hi - lo < MAIN_QSORT_SMALL_THRESH
|
||||
|| d > MAIN_QSORT_DEPTH_THRESH
|
||||
) {
|
||||
MainSimpleSort(state, lo, hi, d);
|
||||
if (state->budget < 0)
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
med = (int32_t) mmed3(block[ptr[lo ] + d],
|
||||
block[ptr[hi ] + d],
|
||||
block[ptr[(lo+hi) >> 1] + d]);
|
||||
|
||||
unLo = ltLo = lo;
|
||||
unHi = gtHi = hi;
|
||||
|
||||
while (1) {
|
||||
while (1) {
|
||||
if (unLo > unHi)
|
||||
break;
|
||||
n = ((int32_t)block[ptr[unLo]+d]) - med;
|
||||
if (n == 0) {
|
||||
MSWAP(ptr[unLo], ptr[ltLo]);
|
||||
ltLo++;
|
||||
unLo++;
|
||||
continue;
|
||||
}
|
||||
if (n > 0) break;
|
||||
unLo++;
|
||||
}
|
||||
while (1) {
|
||||
if (unLo > unHi)
|
||||
break;
|
||||
n = ((int32_t)block[ptr[unHi]+d]) - med;
|
||||
if (n == 0) {
|
||||
MSWAP(ptr[unHi], ptr[gtHi]);
|
||||
gtHi--;
|
||||
unHi--;
|
||||
continue;
|
||||
}
|
||||
if (n < 0) break;
|
||||
unHi--;
|
||||
}
|
||||
if (unLo > unHi)
|
||||
break;
|
||||
MSWAP(ptr[unLo], ptr[unHi]);
|
||||
unLo++;
|
||||
unHi--;
|
||||
}
|
||||
|
||||
ASSERTD(unHi == unLo-1, "mainQSort3(2)");
|
||||
|
||||
if (gtHi < ltLo) {
|
||||
MPUSH(lo, hi, d + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
n = mmin(ltLo-lo, unLo-ltLo); mvswap(ptr, lo, unLo-n, n);
|
||||
m = mmin(hi-gtHi, gtHi-unHi); mvswap(ptr, unLo, hi-m+1, m);
|
||||
|
||||
n = lo + unLo - ltLo - 1;
|
||||
m = hi - (gtHi - unHi) + 1;
|
||||
|
||||
nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
|
||||
nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
|
||||
nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
|
||||
|
||||
if (MNEXTSIZE(0) < MNEXTSIZE(1)) MNEXTSWAP(0, 1);
|
||||
if (MNEXTSIZE(1) < MNEXTSIZE(2)) MNEXTSWAP(1, 2);
|
||||
if (MNEXTSIZE(0) < MNEXTSIZE(1)) MNEXTSWAP(0, 1);
|
||||
|
||||
ASSERTD (MNEXTSIZE(0) >= MNEXTSIZE(1), "mainQSort3(8)");
|
||||
ASSERTD (MNEXTSIZE(1) >= MNEXTSIZE(2), "mainQSort3(9)");
|
||||
|
||||
MPUSH(nextLo[0], nextHi[0], nextD[0]);
|
||||
MPUSH(nextLo[1], nextHi[1], nextD[1]);
|
||||
MPUSH(nextLo[2], nextHi[2], nextD[2]);
|
||||
}
|
||||
}
|
||||
|
||||
#undef MPUSH
|
||||
#undef MPOP
|
||||
#undef MNEXTSIZE
|
||||
#undef MNEXTSWAP
|
||||
#undef MAIN_QSORT_SMALL_THRESH
|
||||
#undef MAIN_QSORT_DEPTH_THRESH
|
||||
#undef MAIN_QSORT_STACK_SIZE
|
||||
|
||||
|
||||
#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
|
||||
#define SETMASK (1 << 21)
|
||||
#define CLEARMASK (~(SETMASK))
|
||||
|
||||
static void MainSort(EState* state)
|
||||
{
|
||||
int32_t i, j;
|
||||
Bool bigDone[256];
|
||||
uint8_t runningOrder[256];
|
||||
|
||||
#define COPYSTART (state->mainSort__copyStart)
|
||||
#define COPYEND (state->mainSort__copyEnd)
|
||||
|
||||
uint32_t *const ptr = state->ptr;
|
||||
uint8_t *const block = state->block;
|
||||
uint32_t *const ftab = state->ftab;
|
||||
const int32_t nblock = state->nblock;
|
||||
uint16_t *const quadrant = state->quadrant;
|
||||
|
||||
memset(ftab, 0, 65537 * sizeof(ftab[0]));
|
||||
|
||||
j = block[0] << 8;
|
||||
i = nblock - 1;
|
||||
|
||||
#if BZIP2_SPEED >= 2
|
||||
for (; i >= 3; i -= 4) {
|
||||
quadrant[i] = 0;
|
||||
j = (j >> 8) | (((unsigned)block[i]) << 8);
|
||||
ftab[j]++;
|
||||
quadrant[i-1] = 0;
|
||||
j = (j >> 8) | (((unsigned)block[i-1]) << 8);
|
||||
ftab[j]++;
|
||||
quadrant[i-2] = 0;
|
||||
j = (j >> 8) | (((unsigned)block[i-2]) << 8);
|
||||
ftab[j]++;
|
||||
quadrant[i-3] = 0;
|
||||
j = (j >> 8) | (((unsigned)block[i-3]) << 8);
|
||||
ftab[j]++;
|
||||
}
|
||||
#endif
|
||||
for (; i >= 0; i--) {
|
||||
quadrant[i] = 0;
|
||||
j = (j >> 8) | (((unsigned)block[i]) << 8);
|
||||
ftab[j]++;
|
||||
}
|
||||
|
||||
for (i = 0; i < BZ_N_OVERSHOOT; i++) {
|
||||
block [nblock+i] = block[i];
|
||||
quadrant[nblock+i] = 0;
|
||||
}
|
||||
|
||||
j = ftab[0];
|
||||
for (i = 1; i <= 65536; i++) {
|
||||
j += ftab[i];
|
||||
ftab[i] = j;
|
||||
}
|
||||
|
||||
{
|
||||
unsigned s;
|
||||
s = block[0] << 8;
|
||||
i = nblock - 1;
|
||||
#if BZIP2_SPEED >= 2
|
||||
for (; i >= 3; i -= 4) {
|
||||
s = (s >> 8) | (block[i] << 8);
|
||||
j = ftab[s] - 1;
|
||||
ftab[s] = j;
|
||||
ptr[j] = i;
|
||||
s = (s >> 8) | (block[i-1] << 8);
|
||||
j = ftab[s] - 1;
|
||||
ftab[s] = j;
|
||||
ptr[j] = i-1;
|
||||
s = (s >> 8) | (block[i-2] << 8);
|
||||
j = ftab[s] - 1;
|
||||
ftab[s] = j;
|
||||
ptr[j] = i-2;
|
||||
s = (s >> 8) | (block[i-3] << 8);
|
||||
j = ftab[s] - 1;
|
||||
ftab[s] = j;
|
||||
ptr[j] = i-3;
|
||||
}
|
||||
#endif
|
||||
for (; i >= 0; i--) {
|
||||
s = (s >> 8) | (block[i] << 8);
|
||||
j = ftab[s] - 1;
|
||||
ftab[s] = j;
|
||||
ptr[j] = i;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= 255; i++) {
|
||||
bigDone [i] = FALSE;
|
||||
runningOrder[i] = i;
|
||||
}
|
||||
|
||||
{
|
||||
unsigned h = 364;
|
||||
|
||||
do {
|
||||
|
||||
h = (h * 171) >> 9;
|
||||
for (i = h; i <= 255; i++) {
|
||||
unsigned vv, jh;
|
||||
vv = runningOrder[i];
|
||||
j = i;
|
||||
while (jh = j - h, BIGFREQ(runningOrder[jh]) > BIGFREQ(vv)) {
|
||||
runningOrder[j] = runningOrder[jh];
|
||||
j = jh;
|
||||
if (j < h)
|
||||
break;
|
||||
}
|
||||
runningOrder[j] = vv;
|
||||
}
|
||||
} while (h != 1);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; ; i++) {
|
||||
unsigned ss;
|
||||
|
||||
ss = runningOrder[i];
|
||||
|
||||
|
||||
for (j = 0; j <= 255; j++) {
|
||||
if (j != ss) {
|
||||
unsigned sb;
|
||||
sb = (ss << 8) + j;
|
||||
if (!(ftab[sb] & SETMASK)) {
|
||||
int32_t lo = ftab[sb] ;
|
||||
int32_t hi = (ftab[sb+1] & CLEARMASK) - 1;
|
||||
if (hi > lo) {
|
||||
MainQSort3(state, lo, hi );
|
||||
if (state->budget < 0) return;
|
||||
}
|
||||
}
|
||||
ftab[sb] |= SETMASK;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERTH(!bigDone[ss], 1006);
|
||||
|
||||
{
|
||||
for (j = 0; j <= 255; j++) {
|
||||
COPYSTART[j] = ftab[(j << 8) + ss] & CLEARMASK;
|
||||
COPYEND [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
|
||||
}
|
||||
for (j = ftab[ss << 8] & CLEARMASK; j < COPYSTART[ss]; j++) {
|
||||
unsigned c1;
|
||||
int32_t k;
|
||||
k = ptr[j] - 1;
|
||||
if (k < 0)
|
||||
k += nblock;
|
||||
c1 = block[k];
|
||||
if (!bigDone[c1])
|
||||
ptr[COPYSTART[c1]++] = k;
|
||||
}
|
||||
for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > COPYEND[ss]; j--) {
|
||||
unsigned c1;
|
||||
int32_t k;
|
||||
k = ptr[j]-1;
|
||||
if (k < 0)
|
||||
k += nblock;
|
||||
c1 = block[k];
|
||||
if (!bigDone[c1])
|
||||
ptr[COPYEND[c1]--] = k;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ASSERTH((COPYSTART[ss]-1 == COPYEND[ss]) \
|
||||
|| (COPYSTART[ss] == 0 && COPYEND[ss] == nblock-1), 1007);
|
||||
|
||||
for (j = 0; j <= 255; j++)
|
||||
ftab[(j << 8) + ss] |= SETMASK;
|
||||
|
||||
if (i == 255)
|
||||
break;
|
||||
|
||||
bigDone[ss] = TRUE;
|
||||
|
||||
{
|
||||
unsigned bbStart = ftab[ss << 8] & CLEARMASK;
|
||||
unsigned bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
|
||||
unsigned shifts = 0;
|
||||
|
||||
while ((bbSize >> shifts) > 65534) shifts++;
|
||||
|
||||
for (j = bbSize-1; j >= 0; j--) {
|
||||
unsigned a2update = ptr[bbStart + j];
|
||||
uint16_t qVal = (uint16_t)(j >> shifts);
|
||||
quadrant[a2update] = qVal;
|
||||
if (a2update < BZ_N_OVERSHOOT)
|
||||
quadrant[a2update + nblock] = qVal;
|
||||
}
|
||||
ASSERTH(((bbSize-1) >> shifts) <= 65535, 1002);
|
||||
}
|
||||
}
|
||||
#undef runningOrder
|
||||
#undef COPYSTART
|
||||
#undef COPYEND
|
||||
}
|
||||
|
||||
#undef BIGFREQ
|
||||
#undef SETMASK
|
||||
#undef CLEARMASK
|
||||
|
||||
int32_t BZ2BlockSort(EState* state)
|
||||
{
|
||||
enum { wfact = 30 };
|
||||
unsigned i;
|
||||
int32_t origPtr = origPtr;
|
||||
|
||||
if (state->nblock >= 10000) {
|
||||
i = state->nblock + BZ_N_OVERSHOOT;
|
||||
if (i & 1)
|
||||
i++;
|
||||
state->quadrant = (uint16_t*) &(state->block[i]);
|
||||
|
||||
state->budget = state->nblock * ((wfact-1) / 3);
|
||||
MainSort(state);
|
||||
if (state->budget >= 0)
|
||||
goto good;
|
||||
}
|
||||
FallbackSort(state);
|
||||
good:
|
||||
|
||||
#if BZ_LIGHT_DEBUG
|
||||
origPtr = -1;
|
||||
#endif
|
||||
for (i = 0; i < state->nblock; i++) {
|
||||
if (state->ptr[i] == 0) {
|
||||
origPtr = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERTH(origPtr != -1, 1003);
|
||||
return origPtr;
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
#if defined(FS_VFS) && defined(TOOL_SHELL)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "bzlib_private.h"
|
||||
|
||||
uint32_t BZ2_crc32Table[256] = {
|
||||
|
||||
0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
|
||||
0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
|
||||
0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
|
||||
0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
|
||||
0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
|
||||
0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
|
||||
0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
|
||||
0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
|
||||
0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
|
||||
0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
|
||||
0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
|
||||
0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
|
||||
0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
|
||||
0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
|
||||
0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
|
||||
0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
|
||||
0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
|
||||
0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
|
||||
0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
|
||||
0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
|
||||
0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
|
||||
0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
|
||||
0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
|
||||
0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
|
||||
0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
|
||||
0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
|
||||
0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
|
||||
0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
|
||||
0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
|
||||
0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
|
||||
0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
|
||||
0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
|
||||
0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
|
||||
0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
|
||||
0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
|
||||
0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
|
||||
0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
|
||||
0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
|
||||
0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
|
||||
0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
|
||||
0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
|
||||
0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
|
||||
0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
|
||||
0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
|
||||
0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
|
||||
0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
|
||||
0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
|
||||
0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
|
||||
0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
|
||||
0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
|
||||
0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
|
||||
0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
|
||||
0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
|
||||
0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
|
||||
0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
|
||||
0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
|
||||
0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
|
||||
0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
|
||||
0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
|
||||
0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
|
||||
0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
|
||||
0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
|
||||
0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
|
||||
0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
|
||||
};
|
||||
|
||||
#if BZ_LIGHT_DEBUG
|
||||
static
|
||||
void BzAssertFail(int errcode)
|
||||
{
|
||||
bb_error_msg_and_die("internal error %d", errcode);
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
void PrepareNewBlock(EState* s)
|
||||
{
|
||||
int i;
|
||||
s->nblock = 0;
|
||||
BZ_INITIALISE_CRC(s->blockCRC);
|
||||
for (i = 0; i < 256; i++)
|
||||
s->inUse[i] = 0;
|
||||
s->blockNo++;
|
||||
}
|
||||
|
||||
static void InitRL(EState* s)
|
||||
{
|
||||
s->state_in_ch = 256;
|
||||
s->state_in_len = 0;
|
||||
}
|
||||
|
||||
|
||||
static int IsEmptyRL(EState* s)
|
||||
{
|
||||
return (s->state_in_ch >= 256 || s->state_in_len <= 0);
|
||||
}
|
||||
|
||||
void BZ2BzCompressInit(BzStream *strm, int blockSize100k)
|
||||
{
|
||||
unsigned n;
|
||||
EState* s;
|
||||
|
||||
s = malloc(sizeof(EState));
|
||||
memset(s, 0, sizeof(EState));
|
||||
s->strm = strm;
|
||||
|
||||
n = 100000 * blockSize100k;
|
||||
s->arr1 = malloc(n * sizeof(uint32_t));
|
||||
s->mtfv = (uint16_t*)s->arr1;
|
||||
s->ptr = (uint32_t*)s->arr1;
|
||||
s->arr2 = malloc((n + BZ_N_OVERSHOOT) * sizeof(uint32_t));
|
||||
s->block = (uint8_t*)s->arr2;
|
||||
s->ftab = malloc(65537 * sizeof(uint32_t));
|
||||
|
||||
s->state = BZ_S_INPUT;
|
||||
s->mode = BZ_M_RUNNING;
|
||||
s->blockSize100k = blockSize100k;
|
||||
s->nblockMAX = n - 19;
|
||||
|
||||
strm->state = s;
|
||||
strm->total_out = 0;
|
||||
InitRL(s);
|
||||
PrepareNewBlock(s);
|
||||
}
|
||||
|
||||
static void AddPairToBlock(EState* s)
|
||||
{
|
||||
int32_t i;
|
||||
uint8_t ch = (uint8_t)(s->state_in_ch);
|
||||
for (i = 0; i < s->state_in_len; i++) {
|
||||
BZ_UPDATE_CRC(s->blockCRC, ch);
|
||||
}
|
||||
s->inUse[s->state_in_ch] = 1;
|
||||
switch (s->state_in_len) {
|
||||
case 3:
|
||||
s->block[s->nblock] = (uint8_t)ch; s->nblock++;
|
||||
case 2:
|
||||
s->block[s->nblock] = (uint8_t)ch; s->nblock++;
|
||||
case 1:
|
||||
s->block[s->nblock] = (uint8_t)ch; s->nblock++;
|
||||
break;
|
||||
default:
|
||||
s->inUse[s->state_in_len - 4] = 1;
|
||||
s->block[s->nblock] = (uint8_t)ch; s->nblock++;
|
||||
s->block[s->nblock] = (uint8_t)ch; s->nblock++;
|
||||
s->block[s->nblock] = (uint8_t)ch; s->nblock++;
|
||||
s->block[s->nblock] = (uint8_t)ch; s->nblock++;
|
||||
s->block[s->nblock] = (uint8_t)(s->state_in_len - 4);
|
||||
s->nblock++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void FlushRL(EState* s)
|
||||
{
|
||||
if (s->state_in_ch < 256) AddPairToBlock(s);
|
||||
InitRL(s);
|
||||
}
|
||||
|
||||
#define ADD_CHAR_TO_BLOCK(zs, zchh0) { \
|
||||
uint32_t zchh = (uint32_t)(zchh0); \
|
||||
if (zchh != zs->state_in_ch && zs->state_in_len == 1) { \
|
||||
uint8_t ch = (uint8_t)(zs->state_in_ch); \
|
||||
BZ_UPDATE_CRC(zs->blockCRC, ch); \
|
||||
zs->inUse[zs->state_in_ch] = 1; \
|
||||
zs->block[zs->nblock] = (uint8_t)ch; \
|
||||
zs->nblock++; \
|
||||
zs->state_in_ch = zchh; \
|
||||
} else \
|
||||
if (zchh != zs->state_in_ch || zs->state_in_len == 255) { \
|
||||
if (zs->state_in_ch < 256) \
|
||||
AddPairToBlock(zs); \
|
||||
zs->state_in_ch = zchh; \
|
||||
zs->state_in_len = 1; \
|
||||
} else { \
|
||||
zs->state_in_len++; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
static void CopyInputUntilStop(EState* s)
|
||||
{
|
||||
#ifdef SAME_CODE_AS_BELOW
|
||||
if (s->mode == BZ_M_RUNNING) {
|
||||
while (1) {
|
||||
if (s->strm->avail_in == 0) break;
|
||||
if (s->nblock >= s->nblockMAX) break;
|
||||
ADD_CHAR_TO_BLOCK(s, (uint32_t)(*(uint8_t*)(s->strm->next_in)));
|
||||
s->strm->next_in++;
|
||||
s->strm->avail_in--;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
while (1) {
|
||||
if (s->strm->avail_in == 0) break;
|
||||
if (s->nblock >= s->nblockMAX) break;
|
||||
ADD_CHAR_TO_BLOCK(s, *(uint8_t*)(s->strm->next_in));
|
||||
s->strm->next_in++;
|
||||
s->strm->avail_in--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CopyOutputUntilStop(EState* s)
|
||||
{
|
||||
while (1) {
|
||||
if (s->strm->avail_out == 0) break;
|
||||
if (s->state_out_pos >= s->posZ) break;
|
||||
*(s->strm->next_out) = *s->state_out_pos++;
|
||||
s->strm->avail_out--;
|
||||
s->strm->next_out++;
|
||||
s->strm->total_out++;
|
||||
}
|
||||
}
|
||||
|
||||
static void HandleCompress(BzStream *strm)
|
||||
{
|
||||
EState* s = strm->state;
|
||||
|
||||
while (1) {
|
||||
if (s->state == BZ_S_OUTPUT) {
|
||||
CopyOutputUntilStop(s);
|
||||
if (s->state_out_pos < s->posZ) break;
|
||||
if (s->mode == BZ_M_FINISHING
|
||||
&& s->strm->avail_in == 0
|
||||
&& IsEmptyRL(s))
|
||||
break;
|
||||
PrepareNewBlock(s);
|
||||
s->state = BZ_S_INPUT;
|
||||
#ifdef FLUSH_IS_UNUSED
|
||||
if (s->mode == BZ_M_FLUSHING
|
||||
&& s->avail_in_expect == 0
|
||||
&& IsEmptyRL(s))
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (s->state == BZ_S_INPUT) {
|
||||
CopyInputUntilStop(s);
|
||||
if (s->mode != BZ_M_RUNNING && s->strm->avail_in == 0) {
|
||||
FlushRL(s);
|
||||
BZ2CompressBlock(s, (s->mode == BZ_M_FINISHING));
|
||||
s->state = BZ_S_OUTPUT;
|
||||
} else
|
||||
if (s->nblock >= s->nblockMAX) {
|
||||
BZ2CompressBlock(s, 0);
|
||||
s->state = BZ_S_OUTPUT;
|
||||
} else
|
||||
if (s->strm->avail_in == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int BZ2BzCompress(BzStream *strm, int action)
|
||||
{
|
||||
EState* s;
|
||||
|
||||
s = strm->state;
|
||||
|
||||
switch (s->mode) {
|
||||
case BZ_M_RUNNING:
|
||||
if (action == BZ_RUN) {
|
||||
HandleCompress(strm);
|
||||
return BZ_RUN_OK;
|
||||
}
|
||||
#ifdef FLUSH_IS_UNUSED
|
||||
else
|
||||
if (action == BZ_FLUSH) {
|
||||
s->mode = BZ_M_FLUSHING;
|
||||
goto case_BZ_M_FLUSHING;
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
s->mode = BZ_M_FINISHING;
|
||||
goto case_BZ_M_FINISHING;
|
||||
}
|
||||
|
||||
#ifdef FLUSH_IS_UNUSED
|
||||
case_BZ_M_FLUSHING:
|
||||
case BZ_M_FLUSHING:
|
||||
HandleCompress(strm);
|
||||
if (s->avail_in_expect > 0 || !IsEmptyRL(s) || s->state_out_pos < s->posZ)
|
||||
return BZ_FLUSH_OK;
|
||||
s->mode = BZ_M_RUNNING;
|
||||
return BZ_RUN_OK;
|
||||
#endif
|
||||
|
||||
case_BZ_M_FINISHING:
|
||||
default:
|
||||
|
||||
HandleCompress(strm);
|
||||
if (s->strm->avail_in > 0 || !IsEmptyRL(s) || s->state_out_pos < s->posZ)
|
||||
return BZ_FINISH_OK;
|
||||
return BZ_STREAM_END;
|
||||
}
|
||||
}
|
||||
|
||||
void BZ2BzCompressEnd(BzStream *strm)
|
||||
{
|
||||
EState* s;
|
||||
|
||||
s = strm->state;
|
||||
free(s->arr1);
|
||||
free(s->arr2);
|
||||
free(s->ftab);
|
||||
free(s);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
#define BZ_RUN 0
|
||||
#define BZ_FLUSH 1
|
||||
#define BZ_FINISH 2
|
||||
|
||||
#define BZ_OK 0
|
||||
#define BZ_RUN_OK 1
|
||||
#define BZ_FLUSH_OK 2
|
||||
#define BZ_FINISH_OK 3
|
||||
#define BZ_STREAM_END 4
|
||||
#define BZ_SEQUENCE_ERROR (-1)
|
||||
#define BZ_PARAM_ERROR (-2)
|
||||
#define BZ_MEM_ERROR (-3)
|
||||
#define BZ_DATA_ERROR (-4)
|
||||
#define BZ_DATA_ERROR_MAGIC (-5)
|
||||
#define BZ_IO_ERROR (-6)
|
||||
#define BZ_UNEXPECTED_EOF (-7)
|
||||
#define BZ_OUTBUFF_FULL (-8)
|
||||
#define BZ_CONFIG_ERROR (-9)
|
||||
|
||||
typedef struct BzStream {
|
||||
void *state;
|
||||
char *next_in;
|
||||
char *next_out;
|
||||
unsigned avail_in;
|
||||
unsigned avail_out;
|
||||
unsigned long long total_out;
|
||||
} BzStream;
|
||||
|
||||
|
||||
void BZ2BzCompressInit(BzStream *strm, int blockSize100k);
|
||||
int BZ2BzCompress(BzStream *strm, int action);
|
||||
void BZ2BzCompressEnd(BzStream *strm);
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bzlib.h"
|
||||
|
||||
typedef unsigned char Bool;
|
||||
|
||||
#define TRUE ((Bool)1)
|
||||
#define FALSE ((Bool)0)
|
||||
|
||||
#if BZ_LIGHT_DEBUG
|
||||
static void BzAssertFail(int errcode) NORETURN;
|
||||
#define ASSERTH(cond, errcode) do { \
|
||||
if (!(cond)) \
|
||||
BzAssertFail(errcode); \
|
||||
} while (0)
|
||||
#else
|
||||
#define ASSERTH(cond, msg) do { } while (0)
|
||||
#endif
|
||||
|
||||
#if BZ_DEBUG
|
||||
#define ASSERTD(cond, msg) do { \
|
||||
if (!(cond)) \
|
||||
bb_error_msg_and_die("(debug build): internal error %s", msg); \
|
||||
} while (0)
|
||||
#else
|
||||
#define ASSERTD(cond, msg) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define BZ_HDR_B 0x42
|
||||
#define BZ_HDR_Z 0x5a
|
||||
#define BZ_HDR_H 0x68
|
||||
#define BZ_HDR_0 0x30
|
||||
|
||||
#define BZ_HDR_BZH0 0x425a6830
|
||||
|
||||
|
||||
#define BZ_MAX_ALPHA_SIZE 258
|
||||
#define BZ_MAX_CODE_LEN 23
|
||||
|
||||
#define BZ_RUNA 0
|
||||
#define BZ_RUNB 1
|
||||
|
||||
#define BZ_N_GROUPS 6
|
||||
#define BZ_G_SIZE 50
|
||||
#define BZ_N_ITERS 4
|
||||
|
||||
#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
|
||||
|
||||
|
||||
extern uint32_t BZ2_crc32Table[256];
|
||||
|
||||
#define BZ_INITIALISE_CRC(crcVar) { \
|
||||
crcVar = 0xffffffffL; \
|
||||
}
|
||||
|
||||
#define BZ_FINALISE_CRC(crcVar) { \
|
||||
crcVar = ~(crcVar); \
|
||||
}
|
||||
|
||||
#define BZ_UPDATE_CRC(crcVar,cha) { \
|
||||
crcVar = (crcVar << 8) ^ \
|
||||
BZ2_crc32Table[(crcVar >> 24) ^ \
|
||||
((uint8_t)cha)]; \
|
||||
}
|
||||
|
||||
|
||||
#define BZ_M_IDLE 1
|
||||
#define BZ_M_RUNNING 2
|
||||
#define BZ_M_FLUSHING 3
|
||||
#define BZ_M_FINISHING 4
|
||||
|
||||
#define BZ_S_OUTPUT 1
|
||||
#define BZ_S_INPUT 2
|
||||
|
||||
#define BZ_N_RADIX 2
|
||||
#define BZ_N_QSORT 12
|
||||
#define BZ_N_SHELL 18
|
||||
#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
|
||||
|
||||
|
||||
|
||||
typedef struct EState {
|
||||
BzStream *strm;
|
||||
|
||||
uint8_t mode;
|
||||
uint8_t state;
|
||||
|
||||
uint8_t blockSize100k;
|
||||
|
||||
uint32_t *arr1;
|
||||
uint32_t *arr2;
|
||||
uint32_t *ftab;
|
||||
|
||||
uint16_t *quadrant;
|
||||
int32_t budget;
|
||||
|
||||
uint32_t *ptr;
|
||||
uint8_t *block;
|
||||
uint16_t *mtfv;
|
||||
uint8_t *zbits;
|
||||
|
||||
uint32_t state_in_ch;
|
||||
int32_t state_in_len;
|
||||
|
||||
int32_t nblock;
|
||||
int32_t nblockMAX;
|
||||
uint8_t *posZ;
|
||||
uint8_t *state_out_pos;
|
||||
|
||||
uint32_t bsBuff;
|
||||
int32_t bsLive;
|
||||
|
||||
uint32_t blockCRC;
|
||||
uint32_t combinedCRC;
|
||||
|
||||
int32_t blockNo;
|
||||
|
||||
int32_t nMTF;
|
||||
|
||||
int32_t nInUse;
|
||||
Bool inUse[256] __attribute__((__aligned__(sizeof(long))));
|
||||
uint8_t unseqToSeq[256];
|
||||
|
||||
int32_t mtfFreq [BZ_MAX_ALPHA_SIZE];
|
||||
uint8_t selector [BZ_MAX_SELECTORS];
|
||||
uint8_t selectorMtf[BZ_MAX_SELECTORS];
|
||||
|
||||
uint8_t len[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
|
||||
int32_t sendMTFValues__code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
int32_t sendMTFValues__rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
#if BZIP2_SPEED >= 5
|
||||
uint32_t sendMTFValues__len_pack[BZ_MAX_ALPHA_SIZE][4];
|
||||
#endif
|
||||
int32_t BZ2_hbMakeCodeLengths__heap [BZ_MAX_ALPHA_SIZE + 2];
|
||||
int32_t BZ2_hbMakeCodeLengths__weight[BZ_MAX_ALPHA_SIZE * 2];
|
||||
int32_t BZ2_hbMakeCodeLengths__parent[BZ_MAX_ALPHA_SIZE * 2];
|
||||
|
||||
int32_t mainSort__copyStart[256];
|
||||
int32_t mainSort__copyEnd[256];
|
||||
} EState;
|
||||
|
||||
int32_t BZ2BlockSort(EState*);
|
||||
|
||||
void BZ2CompressBlock(EState*, int);
|
||||
|
||||
void BZ2BsInitWrite(EState*);
|
||||
|
||||
void BZ2HbAssignCodes(int32_t*, uint8_t*, int32_t, int32_t, int32_t);
|
||||
|
||||
void BZ2HbMakeCodeLengths(EState*, uint8_t*, int32_t*, int32_t, int32_t);
|
||||
|
||||
@@ -0,0 +1,577 @@
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
#if defined(FS_VFS) && defined(TOOL_SHELL)
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bzlib_private.h"
|
||||
|
||||
#if BZIP2_SPEED >= 5
|
||||
# define ALWAYS_INLINE_5 ALWAYS_INLINE
|
||||
#else
|
||||
# define ALWAYS_INLINE_5
|
||||
#endif
|
||||
|
||||
void BZ2BsInitWrite(EState* s)
|
||||
{
|
||||
s->bsLive = 0;
|
||||
s->bsBuff = 0;
|
||||
}
|
||||
|
||||
static void BsFinishWrite(EState* s)
|
||||
{
|
||||
while (s->bsLive > 0) {
|
||||
*s->posZ++ = (uint8_t)(s->bsBuff >> 24);
|
||||
s->bsBuff <<= 8;
|
||||
s->bsLive -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE_5
|
||||
void bsW(EState* s, int32_t n, uint32_t v)
|
||||
{
|
||||
while (s->bsLive >= 8) {
|
||||
*s->posZ++ = (uint8_t)(s->bsBuff >> 24);
|
||||
s->bsBuff <<= 8;
|
||||
s->bsLive -= 8;
|
||||
}
|
||||
s->bsBuff |= (v << (32 - s->bsLive - n));
|
||||
s->bsLive += n;
|
||||
}
|
||||
|
||||
static
|
||||
ALWAYS_INLINE_5
|
||||
void bsW16(EState* s, uint32_t v)
|
||||
{
|
||||
while (s->bsLive >= 8) {
|
||||
*s->posZ++ = (uint8_t)(s->bsBuff >> 24);
|
||||
s->bsBuff <<= 8;
|
||||
s->bsLive -= 8;
|
||||
}
|
||||
s->bsBuff |= (v << (16 - s->bsLive));
|
||||
s->bsLive += 16;
|
||||
}
|
||||
|
||||
static inline void bsW1_1(EState* s)
|
||||
{
|
||||
if (s->bsLive >= 8) {
|
||||
*s->posZ++ = (uint8_t)(s->bsBuff >> 24);
|
||||
s->bsBuff <<= 8;
|
||||
s->bsLive -= 8;
|
||||
}
|
||||
s->bsBuff |= (1 << (31 - s->bsLive));
|
||||
s->bsLive += 1;
|
||||
}
|
||||
static
|
||||
ALWAYS_INLINE_5
|
||||
void bsW1_0(EState* s)
|
||||
{
|
||||
if (s->bsLive >= 8) {
|
||||
*s->posZ++ = (uint8_t)(s->bsBuff >> 24);
|
||||
s->bsBuff <<= 8;
|
||||
s->bsLive -= 8;
|
||||
}
|
||||
s->bsLive += 1;
|
||||
}
|
||||
|
||||
static inline void bsPutU16(EState* s, unsigned u)
|
||||
{
|
||||
bsW16(s, u);
|
||||
}
|
||||
|
||||
static
|
||||
void bsPutU32(EState* s, unsigned u)
|
||||
{
|
||||
bsW16(s, (u >> 16) & 0xffff);
|
||||
bsW16(s, u & 0xffff);
|
||||
}
|
||||
|
||||
static
|
||||
void MakeMapsE(EState* s)
|
||||
{
|
||||
int i;
|
||||
unsigned cnt = 0;
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (s->inUse[i]) {
|
||||
s->unseqToSeq[i] = cnt;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
s->nInUse = cnt;
|
||||
}
|
||||
|
||||
static
|
||||
#if defined __i386__
|
||||
NOINLINE
|
||||
#endif
|
||||
int InnerLoop(uint8_t *yy, uint8_t ll_i)
|
||||
{
|
||||
register uint8_t rtmp;
|
||||
register uint8_t* ryy_j;
|
||||
rtmp = yy[1];
|
||||
yy[1] = yy[0];
|
||||
ryy_j = &(yy[1]);
|
||||
while (ll_i != rtmp) {
|
||||
register uint8_t rtmp2;
|
||||
ryy_j++;
|
||||
rtmp2 = rtmp;
|
||||
rtmp = *ryy_j;
|
||||
*ryy_j = rtmp2;
|
||||
}
|
||||
yy[0] = rtmp;
|
||||
return ryy_j - &(yy[0]);
|
||||
}
|
||||
static void GenerateMTFValues(EState* s)
|
||||
{
|
||||
uint8_t yy[256];
|
||||
int i;
|
||||
int zPend;
|
||||
int32_t wr;
|
||||
|
||||
uint32_t* ptr = s->ptr;
|
||||
|
||||
MakeMapsE(s);
|
||||
|
||||
wr = 0;
|
||||
zPend = 0;
|
||||
for (i = 0; i <= s->nInUse+1; i++)
|
||||
s->mtfFreq[i] = 0;
|
||||
|
||||
for (i = 0; i < s->nInUse; i++)
|
||||
yy[i] = (uint8_t) i;
|
||||
|
||||
for (i = 0; i < s->nblock; i++) {
|
||||
uint8_t ll_i = ll_i;
|
||||
int32_t j;
|
||||
|
||||
ASSERTD(wr <= i, "generateMTFValues(1)");
|
||||
j = ptr[i] - 1;
|
||||
if (j < 0)
|
||||
j += s->nblock;
|
||||
ll_i = s->unseqToSeq[s->block[j]];
|
||||
ASSERTD(ll_i < s->nInUse, "generateMTFValues(2a)");
|
||||
|
||||
if (yy[0] == ll_i) {
|
||||
zPend++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (zPend > 0) {
|
||||
process_zPend:
|
||||
zPend--;
|
||||
while (1) {
|
||||
#if 0
|
||||
if (zPend & 1) {
|
||||
s->mtfv[wr] = BZ_RUNB; wr++;
|
||||
s->mtfFreq[BZ_RUNB]++;
|
||||
} else {
|
||||
s->mtfv[wr] = BZ_RUNA; wr++;
|
||||
s->mtfFreq[BZ_RUNA]++;
|
||||
}
|
||||
#else
|
||||
unsigned run = zPend & 1;
|
||||
s->mtfv[wr] = run;
|
||||
wr++;
|
||||
s->mtfFreq[run]++;
|
||||
#endif
|
||||
zPend -= 2;
|
||||
if (zPend < 0)
|
||||
break;
|
||||
zPend = (unsigned)zPend / 2;
|
||||
}
|
||||
if (i < 0)
|
||||
goto end;
|
||||
zPend = 0;
|
||||
}
|
||||
j = InnerLoop(yy, ll_i);
|
||||
s->mtfv[wr] = j+1;
|
||||
wr++;
|
||||
s->mtfFreq[j+1]++;
|
||||
}
|
||||
|
||||
i = -1;
|
||||
if (zPend > 0)
|
||||
goto process_zPend;
|
||||
end:
|
||||
s->mtfv[wr] = s->nInUse+1;
|
||||
wr++;
|
||||
s->mtfFreq[s->nInUse+1]++;
|
||||
|
||||
s->nMTF = wr;
|
||||
}
|
||||
|
||||
#define BZ_LESSER_ICOST 0
|
||||
#define BZ_GREATER_ICOST 15
|
||||
|
||||
static void SendMTFValues(EState* s)
|
||||
{
|
||||
int32_t t, i;
|
||||
unsigned iter;
|
||||
unsigned gs;
|
||||
int32_t alphaSize;
|
||||
unsigned nSelectors, selCtr;
|
||||
int32_t nGroups;
|
||||
|
||||
#define CODE sendMTFValues__code
|
||||
#define RFREQ sendMTFValues__rfreq
|
||||
#define LEN_PACK sendMTFValues__len_pack
|
||||
|
||||
unsigned cost[BZ_N_GROUPS];
|
||||
|
||||
uint16_t* mtfv = s->mtfv;
|
||||
|
||||
alphaSize = s->nInUse + 2;
|
||||
for (t = 0; t < BZ_N_GROUPS; t++) {
|
||||
unsigned v;
|
||||
for (v = 0; v < alphaSize; v++)
|
||||
s->len[t][v] = BZ_GREATER_ICOST;
|
||||
}
|
||||
|
||||
ASSERTH(s->nMTF > 0, 3001);
|
||||
nGroups = 2;
|
||||
nGroups += (s->nMTF >= 200);
|
||||
nGroups += (s->nMTF >= 600);
|
||||
nGroups += (s->nMTF >= 1200);
|
||||
nGroups += (s->nMTF >= 2400);
|
||||
|
||||
{
|
||||
unsigned nPart, remF;
|
||||
|
||||
nPart = nGroups;
|
||||
remF = s->nMTF;
|
||||
gs = 0;
|
||||
while (nPart > 0) {
|
||||
unsigned v;
|
||||
unsigned ge;
|
||||
unsigned tFreq, aFreq;
|
||||
|
||||
tFreq = remF / nPart;
|
||||
ge = gs;
|
||||
aFreq = 0;
|
||||
while (aFreq < tFreq && ge < alphaSize) {
|
||||
aFreq += s->mtfFreq[ge++];
|
||||
}
|
||||
ge--;
|
||||
|
||||
if (ge > gs
|
||||
&& nPart != nGroups && nPart != 1
|
||||
&& ((nGroups - nPart) % 2 == 1)
|
||||
) {
|
||||
aFreq -= s->mtfFreq[ge];
|
||||
ge--;
|
||||
}
|
||||
|
||||
for (v = 0; v < alphaSize; v++)
|
||||
if (v >= gs && v <= ge)
|
||||
s->len[nPart-1][v] = BZ_LESSER_ICOST;
|
||||
else
|
||||
s->len[nPart-1][v] = BZ_GREATER_ICOST;
|
||||
|
||||
nPart--;
|
||||
gs = ge + 1;
|
||||
remF -= aFreq;
|
||||
}
|
||||
}
|
||||
|
||||
for (iter = 0; iter < BZ_N_ITERS; iter++) {
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
unsigned v;
|
||||
for (v = 0; v < alphaSize; v++)
|
||||
s->RFREQ[t][v] = 0;
|
||||
}
|
||||
|
||||
#if BZIP2_SPEED >= 5
|
||||
if (nGroups == 6) {
|
||||
unsigned v;
|
||||
for (v = 0; v < alphaSize; v++) {
|
||||
s->LEN_PACK[v][0] = (s->len[1][v] << 16) | s->len[0][v];
|
||||
s->LEN_PACK[v][1] = (s->len[3][v] << 16) | s->len[2][v];
|
||||
s->LEN_PACK[v][2] = (s->len[5][v] << 16) | s->len[4][v];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
nSelectors = 0;
|
||||
gs = 0;
|
||||
while (1) {
|
||||
unsigned ge;
|
||||
unsigned bt, bc;
|
||||
|
||||
if (gs >= s->nMTF)
|
||||
break;
|
||||
ge = gs + BZ_G_SIZE - 1;
|
||||
if (ge >= s->nMTF)
|
||||
ge = s->nMTF-1;
|
||||
|
||||
for (t = 0; t < nGroups; t++)
|
||||
cost[t] = 0;
|
||||
#if BZIP2_SPEED >= 5
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
register uint32_t cost01, cost23, cost45;
|
||||
register uint16_t icv;
|
||||
cost01 = cost23 = cost45 = 0;
|
||||
#define BZ_ITER(nn) \
|
||||
icv = mtfv[gs+(nn)]; \
|
||||
cost01 += s->LEN_PACK[icv][0]; \
|
||||
cost23 += s->LEN_PACK[icv][1]; \
|
||||
cost45 += s->LEN_PACK[icv][2];
|
||||
|
||||
BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
|
||||
BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
|
||||
BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
|
||||
BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
|
||||
BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
|
||||
BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
|
||||
BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
|
||||
BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
|
||||
BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
|
||||
BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
|
||||
#undef BZ_ITER
|
||||
cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
|
||||
cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
|
||||
cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
for (i = gs; i <= ge; i++) {
|
||||
unsigned icv = mtfv[i];
|
||||
for (t = 0; t < nGroups; t++)
|
||||
cost[t] += s->len[t][icv];
|
||||
}
|
||||
}
|
||||
bc = cost[0];
|
||||
bt = 0;
|
||||
for (t = 1; t < nGroups; t++) {
|
||||
if (cost[t] < bc) {
|
||||
bc = cost[t];
|
||||
bt = t;
|
||||
}
|
||||
}
|
||||
s->selector[nSelectors] = bt;
|
||||
nSelectors++;
|
||||
|
||||
#if BZIP2_SPEED >= 4
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
#define BZ_ITUR(nn) s->RFREQ[bt][mtfv[gs + (nn)]]++
|
||||
BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
|
||||
BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
|
||||
BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
|
||||
BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
|
||||
BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
|
||||
BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
|
||||
BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
|
||||
BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
|
||||
BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
|
||||
BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
|
||||
#undef BZ_ITUR
|
||||
gs = ge + 1;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
while (gs <= ge) {
|
||||
s->RFREQ[bt][mtfv[gs]]++;
|
||||
gs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (t = 0; t < nGroups; t++)
|
||||
BZ2HbMakeCodeLengths(s, &(s->len[t][0]), &(s->RFREQ[t][0]), alphaSize, 17 );
|
||||
}
|
||||
|
||||
ASSERTH(nGroups < 8, 3002);
|
||||
ASSERTH(nSelectors < 32768 && nSelectors <= (2 + (900000 / BZ_G_SIZE)), 3003);
|
||||
|
||||
{
|
||||
uint8_t pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
|
||||
|
||||
for (i = 0; i < nGroups; i++)
|
||||
pos[i] = i;
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
unsigned j;
|
||||
ll_i = s->selector[i];
|
||||
j = 0;
|
||||
tmp = pos[j];
|
||||
while (ll_i != tmp) {
|
||||
j++;
|
||||
tmp2 = tmp;
|
||||
tmp = pos[j];
|
||||
pos[j] = tmp2;
|
||||
}
|
||||
pos[0] = tmp;
|
||||
s->selectorMtf[i] = j;
|
||||
}
|
||||
}
|
||||
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
unsigned minLen = 32;
|
||||
unsigned maxLen = 0;
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
|
||||
if (s->len[t][i] < minLen) minLen = s->len[t][i];
|
||||
}
|
||||
ASSERTH(!(maxLen > 17), 3004);
|
||||
ASSERTH(!(minLen < 1), 3005);
|
||||
BZ2HbAssignCodes(&(s->CODE[t][0]), &(s->len[t][0]), minLen, maxLen, alphaSize);
|
||||
}
|
||||
|
||||
{
|
||||
int inUse16 = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (sizeof(long) <= 4) {
|
||||
inUse16 = inUse16*2 +
|
||||
((*(uint32_t*)&(s->inUse[i * 16 + 0])
|
||||
| *(uint32_t*)&(s->inUse[i * 16 + 4])
|
||||
| *(uint32_t*)&(s->inUse[i * 16 + 8])
|
||||
| *(uint32_t*)&(s->inUse[i * 16 + 12])) != 0);
|
||||
} else {
|
||||
inUse16 = inUse16*2 +
|
||||
((*(uint64_t*)&(s->inUse[i * 16 + 0])
|
||||
| *(uint64_t*)&(s->inUse[i * 16 + 8])) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
bsW16(s, inUse16);
|
||||
|
||||
inUse16 <<= (sizeof(int)*8 - 16);
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (inUse16 < 0) {
|
||||
unsigned v16 = 0;
|
||||
unsigned j;
|
||||
for (j = 0; j < 16; j++)
|
||||
v16 = v16*2 + s->inUse[i * 16 + j];
|
||||
bsW16(s, v16);
|
||||
}
|
||||
inUse16 <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
bsW(s, 3, nGroups);
|
||||
bsW(s, 15, nSelectors);
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
unsigned j;
|
||||
for (j = 0; j < s->selectorMtf[i]; j++)
|
||||
bsW1_1(s);
|
||||
bsW1_0(s);
|
||||
}
|
||||
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
unsigned curr = s->len[t][0];
|
||||
bsW(s, 5, curr);
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
while (curr < s->len[t][i]) { bsW(s, 2, 2); curr++; }
|
||||
while (curr > s->len[t][i]) { bsW(s, 2, 3); curr--; }
|
||||
bsW1_0(s);
|
||||
}
|
||||
}
|
||||
|
||||
selCtr = 0;
|
||||
gs = 0;
|
||||
while (1) {
|
||||
unsigned ge;
|
||||
|
||||
if (gs >= s->nMTF)
|
||||
break;
|
||||
ge = gs + BZ_G_SIZE - 1;
|
||||
if (ge >= s->nMTF)
|
||||
ge = s->nMTF-1;
|
||||
ASSERTH(s->selector[selCtr] < nGroups, 3006);
|
||||
|
||||
#if 0
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
uint16_t mtfv_i;
|
||||
uint8_t* s_len_sel_selCtr = &(s->len[s->selector[selCtr]][0]);
|
||||
int32_t* s_code_sel_selCtr = &(s->CODE[s->selector[selCtr]][0]);
|
||||
#define BZ_ITAH(nn) \
|
||||
mtfv_i = mtfv[gs+(nn)]; \
|
||||
bsW(s, s_len_sel_selCtr[mtfv_i], s_code_sel_selCtr[mtfv_i])
|
||||
BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
|
||||
BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
|
||||
BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
|
||||
BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
|
||||
BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
|
||||
BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
|
||||
BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
|
||||
BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
|
||||
BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
|
||||
BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
|
||||
#undef BZ_ITAH
|
||||
gs = ge+1;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
uint8_t* s_len_sel_selCtr = &(s->len [s->selector[selCtr]][0]);
|
||||
int32_t* s_code_sel_selCtr = &(s->CODE[s->selector[selCtr]][0]);
|
||||
while (gs <= ge) {
|
||||
bsW(s,
|
||||
s_len_sel_selCtr[mtfv[gs]],
|
||||
s_code_sel_selCtr[mtfv[gs]]
|
||||
);
|
||||
gs++;
|
||||
}
|
||||
}
|
||||
selCtr++;
|
||||
}
|
||||
ASSERTH(selCtr == nSelectors, 3007);
|
||||
#undef CODE
|
||||
#undef RFREQ
|
||||
#undef LEN_PACK
|
||||
}
|
||||
|
||||
void BZ2CompressBlock(EState* s, int is_last_block)
|
||||
{
|
||||
int32_t origPtr = origPtr;
|
||||
|
||||
if (s->nblock > 0) {
|
||||
BZ_FINALISE_CRC(s->blockCRC);
|
||||
s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
|
||||
s->combinedCRC ^= s->blockCRC;
|
||||
if (s->blockNo > 1)
|
||||
s->posZ = s->zbits;
|
||||
|
||||
origPtr = BZ2BlockSort(s);
|
||||
}
|
||||
|
||||
s->zbits = &((uint8_t*)s->arr2)[s->nblock];
|
||||
s->posZ = s->zbits;
|
||||
s->state_out_pos = s->zbits;
|
||||
|
||||
if (s->blockNo == 1) {
|
||||
BZ2BsInitWrite(s);
|
||||
bsPutU32(s, BZ_HDR_BZH0 + s->blockSize100k);
|
||||
}
|
||||
|
||||
if (s->nblock > 0) {
|
||||
bsPutU32(s, 0x31415926);
|
||||
bsPutU16(s, 0x5359);
|
||||
|
||||
bsPutU32(s, s->blockCRC);
|
||||
|
||||
bsW1_0(s);
|
||||
|
||||
bsW(s, 24, origPtr);
|
||||
GenerateMTFValues(s);
|
||||
SendMTFValues(s);
|
||||
}
|
||||
|
||||
if (is_last_block) {
|
||||
bsPutU32(s, 0x17724538);
|
||||
bsPutU16(s, 0x5090);
|
||||
bsPutU32(s, s->combinedCRC);
|
||||
BsFinishWrite(s);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,179 @@
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
#if defined(FS_VFS) && defined(TOOL_SHELL)
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
|
||||
#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
|
||||
#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
|
||||
|
||||
#define ADDWEIGHTS(zw1,zw2) \
|
||||
(WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
|
||||
(1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
|
||||
|
||||
#define UPHEAP(z) { \
|
||||
int32_t zz, tmp; \
|
||||
zz = z; \
|
||||
tmp = HEAP[zz]; \
|
||||
while (WEIGHT[tmp] < WEIGHT[HEAP[zz >> 1]]) { \
|
||||
HEAP[zz] = HEAP[zz >> 1]; \
|
||||
zz >>= 1; \
|
||||
} \
|
||||
HEAP[zz] = tmp; \
|
||||
}
|
||||
|
||||
#if BZIP2_SPEED >= 1
|
||||
|
||||
#define DOWNHEAP1(heap, weight, Heap) { \
|
||||
int32_t zz, yy, tmp; \
|
||||
zz = 1; \
|
||||
tmp = heap[zz]; \
|
||||
while (1) { \
|
||||
yy = zz << 1; \
|
||||
if (yy > nHeap) \
|
||||
break; \
|
||||
if (yy < nHeap \
|
||||
&& weight[heap[yy+1]] < weight[heap[yy]]) \
|
||||
yy++; \
|
||||
if (weight[tmp] < weight[heap[yy]]) \
|
||||
break; \
|
||||
heap[zz] = heap[yy]; \
|
||||
zz = yy; \
|
||||
} \
|
||||
heap[zz] = tmp; \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void DOWNHEAP1(int32_t *heap, int32_t *weight, int32_t nHeap)
|
||||
{
|
||||
int32_t zz, yy, tmp;
|
||||
zz = 1;
|
||||
tmp = heap[zz];
|
||||
while (1) {
|
||||
yy = zz << 1;
|
||||
if (yy > nHeap)
|
||||
break;
|
||||
if (yy < nHeap
|
||||
&& weight[heap[yy + 1]] < weight[heap[yy]])
|
||||
yy++;
|
||||
if (weight[tmp] < weight[heap[yy]])
|
||||
break;
|
||||
heap[zz] = heap[yy];
|
||||
zz = yy;
|
||||
}
|
||||
heap[zz] = tmp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void BZ2HbMakeCodeLengths(EState *s,
|
||||
uint8_t *len,
|
||||
int32_t *freq,
|
||||
int32_t alphaSize,
|
||||
int32_t maxLen)
|
||||
{
|
||||
int32_t nNodes, nHeap, n1, n2, i, j, k;
|
||||
Bool tooLong;
|
||||
|
||||
#define HEAP (s->BZ2_hbMakeCodeLengths__heap)
|
||||
#define WEIGHT (s->BZ2_hbMakeCodeLengths__weight)
|
||||
#define PARENT (s->BZ2_hbMakeCodeLengths__parent)
|
||||
|
||||
for (i = 0; i < alphaSize; i++)
|
||||
WEIGHT[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
|
||||
|
||||
while (1) {
|
||||
nNodes = alphaSize;
|
||||
nHeap = 0;
|
||||
|
||||
HEAP[0] = 0;
|
||||
WEIGHT[0] = 0;
|
||||
PARENT[0] = -2;
|
||||
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
PARENT[i] = -1;
|
||||
nHeap++;
|
||||
HEAP[nHeap] = i;
|
||||
UPHEAP(nHeap);
|
||||
}
|
||||
|
||||
ASSERTH(nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001);
|
||||
|
||||
while (nHeap > 1) {
|
||||
n1 = HEAP[1]; HEAP[1] = HEAP[nHeap]; nHeap--; DOWNHEAP1(HEAP, WEIGHT, nHeap);
|
||||
n2 = HEAP[1]; HEAP[1] = HEAP[nHeap]; nHeap--; DOWNHEAP1(HEAP, WEIGHT, nHeap);
|
||||
nNodes++;
|
||||
PARENT[n1] = PARENT[n2] = nNodes;
|
||||
WEIGHT[nNodes] = ADDWEIGHTS(WEIGHT[n1], WEIGHT[n2]);
|
||||
PARENT[nNodes] = -1;
|
||||
nHeap++;
|
||||
HEAP[nHeap] = nNodes;
|
||||
UPHEAP(nHeap);
|
||||
}
|
||||
|
||||
ASSERTH(nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002);
|
||||
|
||||
tooLong = FALSE;
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
j = 0;
|
||||
k = i;
|
||||
while (PARENT[k] >= 0) {
|
||||
k = PARENT[k];
|
||||
j++;
|
||||
}
|
||||
len[i-1] = j;
|
||||
if (j > maxLen)
|
||||
tooLong = TRUE;
|
||||
}
|
||||
|
||||
if (!tooLong)
|
||||
break;
|
||||
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
j = WEIGHT[i] >> 8;
|
||||
j = 1 + (j / 2);
|
||||
WEIGHT[i] = j << 8;
|
||||
}
|
||||
}
|
||||
#undef HEAP
|
||||
#undef WEIGHT
|
||||
#undef PARENT
|
||||
}
|
||||
|
||||
void BZ2HbAssignCodes(int32_t *code,
|
||||
uint8_t *length,
|
||||
int32_t minLen,
|
||||
int32_t maxLen,
|
||||
int32_t alphaSize)
|
||||
{
|
||||
int32_t n, vec, i;
|
||||
|
||||
vec = 0;
|
||||
for (n = minLen; n <= maxLen; n++) {
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
if (length[i] == n) {
|
||||
code[i] = vec;
|
||||
vec++;
|
||||
}
|
||||
}
|
||||
vec <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user