1
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
2
2009-08-14 : Igor Pavlov : Public domain */
12
#define SZE_OUT_OVERFLOW SZE_DATA_ERROR
14
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
15
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
17
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
18
int level, UInt32 dictSize, int filterMode)
20
ISzAlloc g_Alloc = { SzAlloc, SzFree };
21
size_t outSize2 = *destLen;
24
int mainResult = SZ_ERROR_OUTPUT_EOF;
26
LzmaEncProps_Init(&props);
28
props.dictSize = dictSize;
31
if (outSize2 < LZMA86_HEADER_SIZE)
32
return SZ_ERROR_OUTPUT_EOF;
37
for (i = 0; i < 8; i++, t >>= 8)
38
dest[LZMA86_SIZE_OFFSET + i] = (Byte)t;
42
useFilter = (filterMode != SZ_FILTER_NO);
47
filteredStream = (Byte *)MyAlloc(srcLen);
48
if (filteredStream == 0)
50
memcpy(filteredStream, src, srcLen);
54
x86_Convert_Init(x86State);
55
x86_Convert(filteredStream, srcLen, 0, &x86State, 1);
61
Bool bestIsFiltered = False;
63
/* passes for SZ_FILTER_AUTO:
66
2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
68
int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
71
for (i = 0; i < numPasses; i++)
73
size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;
74
size_t outPropsSize = 5;
76
Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);
77
if (curModeIsFiltered && !bestIsFiltered)
79
if (useFilter && i == 0)
80
curModeIsFiltered = True;
82
curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,
83
curModeIsFiltered ? filteredStream : src, srcLen,
84
&props, dest + 1, &outPropsSize, 0,
85
NULL, &g_Alloc, &g_Alloc);
87
if (curRes != SZ_ERROR_OUTPUT_EOF)
94
if (outSizeProcessed <= minSize || mainResult != SZ_OK)
96
minSize = outSizeProcessed;
97
bestIsFiltered = curModeIsFiltered;
102
dest[0] = (bestIsFiltered ? 1 : 0);
103
*destLen = LZMA86_HEADER_SIZE + minSize;
106
MyFree(filteredStream);