1 /* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
2 2018-07-04 : Igor Pavlov : Public domain */
14 #define SZE_OUT_OVERFLOW SZE_DATA_ERROR
16 int Lzma86_Encode(Byte
*dest
, size_t *destLen
, const Byte
*src
, size_t srcLen
,
17 int level
, UInt32 dictSize
, int filterMode
)
19 size_t outSize2
= *destLen
;
22 int mainResult
= SZ_ERROR_OUTPUT_EOF
;
24 LzmaEncProps_Init(&props
);
26 props
.dictSize
= dictSize
;
29 if (outSize2
< LZMA86_HEADER_SIZE
)
30 return SZ_ERROR_OUTPUT_EOF
;
35 for (i
= 0; i
< 8; i
++, t
>>= 8)
36 dest
[LZMA86_SIZE_OFFSET
+ i
] = (Byte
)t
;
40 useFilter
= (filterMode
!= SZ_FILTER_NO
);
45 filteredStream
= (Byte
*)MyAlloc(srcLen
);
46 if (filteredStream
== 0)
48 memcpy(filteredStream
, src
, srcLen
);
52 x86_Convert_Init(x86State
);
53 x86_Convert(filteredStream
, srcLen
, 0, &x86State
, 1);
59 BoolInt bestIsFiltered
= False
;
61 /* passes for SZ_FILTER_AUTO:
64 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
66 int numPasses
= (filterMode
== SZ_FILTER_AUTO
) ? 3 : 1;
69 for (i
= 0; i
< numPasses
; i
++)
71 size_t outSizeProcessed
= outSize2
- LZMA86_HEADER_SIZE
;
72 size_t outPropsSize
= 5;
74 BoolInt curModeIsFiltered
= (numPasses
> 1 && i
== numPasses
- 1);
75 if (curModeIsFiltered
&& !bestIsFiltered
)
77 if (useFilter
&& i
== 0)
78 curModeIsFiltered
= True
;
80 curRes
= LzmaEncode(dest
+ LZMA86_HEADER_SIZE
, &outSizeProcessed
,
81 curModeIsFiltered
? filteredStream
: src
, srcLen
,
82 &props
, dest
+ 1, &outPropsSize
, 0,
83 NULL
, &g_Alloc
, &g_Alloc
);
85 if (curRes
!= SZ_ERROR_OUTPUT_EOF
)
92 if (outSizeProcessed
<= minSize
|| mainResult
!= SZ_OK
)
94 minSize
= outSizeProcessed
;
95 bestIsFiltered
= curModeIsFiltered
;
100 dest
[0] = (Byte
)(bestIsFiltered
? 1 : 0);
101 *destLen
= LZMA86_HEADER_SIZE
+ minSize
;
104 MyFree(filteredStream
);