Use custom encoding for LZMA properties.

This commit is contained in:
Markus F.X.J. Oberhumer
2006-06-26 17:28:46 +02:00
parent 8ed280907c
commit 3785479086
12 changed files with 4237 additions and 4207 deletions
+37 -11
View File
@@ -71,11 +71,12 @@ int compress_lzma_dummy = 0;
// while you keep LZMA SDK code unmodified.
/*************************************************************************
// cruft because of pseudo-COM layer
**************************************************************************/
#undef USE_LZMA_PROPERTIES
#undef MSDOS
#undef OS2
#undef _WIN32
@@ -230,6 +231,14 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
if (pr[3].uintVal > src_len)
pr[3].uintVal = src_len;
res->pos_bits = pr[0].uintVal;
res->lit_pos_bits = pr[1].uintVal;
res->lit_context_bits = pr[2].uintVal;
res->dict_size = pr[3].uintVal;
//res->num_probs = LzmaGetNumProbs(&s.Properties));
//res->num_probs = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
res->num_probs = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits));
#ifndef _NO_EXCEPTIONS
try {
#else
@@ -246,7 +255,15 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
goto error;
}
assert(os.Pos == 5);
os.Pos -= 4; // do not encode dict_size
#if defined(USE_LZMA_PROPERTIES)
os.Pos = 1;
#else
os.Pos = 0;
// extra stuff in first byte: 5 high bits convenience for stub decompressor
unsigned t = res->lit_context_bits + res->lit_pos_bits;
os.WriteByte((t << 3) | res->pos_bits);
os.WriteByte((res->lit_pos_bits << 4) | (res->lit_context_bits));
#endif
rh = enc.Code(&is, &os, NULL, NULL, &progress);
@@ -270,14 +287,6 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
r = UPX_E_OK;
}
res->pos_bits = pr[0].uintVal;
res->lit_pos_bits = pr[1].uintVal;
res->lit_context_bits = pr[2].uintVal;
res->dict_size = pr[3].uintVal;
//res->num_probs = LzmaGetNumProbs(&s.Properties));
//res->num_probs = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
res->num_probs = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits));
error:
*dst_len = os.Pos;
return r;
@@ -324,16 +333,33 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
int r = UPX_E_ERROR;
int rh;
#if defined(USE_LZMA_PROPERTIES)
if (src_len < 2)
goto error;
rh = LzmaDecodeProperties(&s.Properties, src, src_len);
if (rh != 0)
goto error;
src += 1; src_len -= 1;
#else
if (src_len < 3)
goto error;
s.Properties.pb = src[0] & 7;
s.Properties.lp = (src[1] >> 4);
s.Properties.lc = src[1] & 15;
if (s.Properties.pb >= 5) goto error;
if (s.Properties.lp >= 5) goto error;
if (s.Properties.lc >= 9) goto error;
// extra
if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp) goto error;
src += 2; src_len -= 2;
#endif
if (result)
{
assert(result->method == method);
assert(result->result_lzma.pos_bits == (unsigned) s.Properties.pb);
assert(result->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp);
assert(result->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
assert(result->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
}
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));