1 /* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
12 #include "../LzmaEnc.h"
14 #define SZE_OUT_OVERFLOW SZE_DATA_ERROR
16 static void *SzAlloc(void *p
, size_t size
) { p
= p
; return MyAlloc(size
); }
17 static void SzFree(void *p
, void *address
) { p
= p
; MyFree(address
); }
18 static ISzAlloc g_Alloc
= { SzAlloc
, SzFree
};
20 #define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE)
21 #define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
23 int Lzma86_Encode(Byte
*dest
, size_t *destLen
, const Byte
*src
, size_t srcLen
,
24 int level
, UInt32 dictSize
, int filterMode
)
26 size_t outSize2
= *destLen
;
29 int mainResult
= SZ_ERROR_OUTPUT_EOF
;
31 LzmaEncProps_Init(&props
);
33 props
.dictSize
= dictSize
;
36 if (outSize2
< LZMA86_HEADER_SIZE
)
37 return SZ_ERROR_OUTPUT_EOF
;
42 for (i
= 0; i
< 8; i
++, t
>>= 8)
43 dest
[LZMA86_SIZE_OFFSET
+ i
] = (Byte
)t
;
47 useFilter
= (filterMode
!= SZ_FILTER_NO
);
52 filteredStream
= (Byte
*)MyAlloc(srcLen
);
53 if (filteredStream
== 0)
55 memcpy(filteredStream
, src
, srcLen
);
59 x86_Convert_Init(x86State
);
60 x86_Convert(filteredStream
, srcLen
, 0, &x86State
, 1);
66 Bool bestIsFiltered
= False
;
68 /* passes for SZ_FILTER_AUTO:
71 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
73 int numPasses
= (filterMode
== SZ_FILTER_AUTO
) ? 3 : 1;
76 for (i
= 0; i
< numPasses
; i
++)
78 size_t outSizeProcessed
= outSize2
- LZMA86_HEADER_SIZE
;
79 size_t outPropsSize
= 5;
81 Bool curModeIsFiltered
= (numPasses
> 1 && i
== numPasses
- 1);
82 if (curModeIsFiltered
&& !bestIsFiltered
)
84 if (useFilter
&& i
== 0)
85 curModeIsFiltered
= True
;
87 curRes
= LzmaEncode(dest
+ LZMA86_HEADER_SIZE
, &outSizeProcessed
,
88 curModeIsFiltered
? filteredStream
: src
, srcLen
,
89 &props
, dest
+ 1, &outPropsSize
, 0,
90 NULL
, &g_Alloc
, &g_Alloc
);
92 if (curRes
!= SZ_ERROR_OUTPUT_EOF
)
99 if (outSizeProcessed
<= minSize
|| mainResult
!= SZ_OK
)
101 minSize
= outSizeProcessed
;
102 bestIsFiltered
= curModeIsFiltered
;
107 dest
[0] = (bestIsFiltered
? 1 : 0);
108 *destLen
= LZMA86_HEADER_SIZE
+ minSize
;
111 MyFree(filteredStream
);