--- /dev/null
+/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder\r
+2018-07-04 : Igor Pavlov : Public domain */\r
+\r
+#include "Precomp.h"\r
+\r
+#include <string.h>\r
+\r
+#include "Lzma86.h"\r
+\r
+#include "Alloc.h"\r
+#include "Bra.h"\r
+#include "LzmaEnc.h"\r
+\r
+int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,\r
+ int level, UInt32 dictSize, int filterMode)\r
+{\r
+ size_t outSize2 = *destLen;\r
+ Byte *filteredStream;\r
+ BoolInt useFilter;\r
+ int mainResult = SZ_ERROR_OUTPUT_EOF;\r
+ CLzmaEncProps props;\r
+ LzmaEncProps_Init(&props);\r
+ props.level = level;\r
+ props.dictSize = dictSize;\r
+ \r
+ *destLen = 0;\r
+ if (outSize2 < LZMA86_HEADER_SIZE)\r
+ return SZ_ERROR_OUTPUT_EOF;\r
+\r
+ {\r
+ int i;\r
+ UInt64 t = srcLen;\r
+ for (i = 0; i < 8; i++, t >>= 8)\r
+ dest[LZMA86_SIZE_OFFSET + i] = (Byte)t;\r
+ }\r
+\r
+ filteredStream = 0;\r
+ useFilter = (filterMode != SZ_FILTER_NO);\r
+ if (useFilter)\r
+ {\r
+ if (srcLen != 0)\r
+ {\r
+ filteredStream = (Byte *)MyAlloc(srcLen);\r
+ if (filteredStream == 0)\r
+ return SZ_ERROR_MEM;\r
+ memcpy(filteredStream, src, srcLen);\r
+ }\r
+ {\r
+ UInt32 x86State;\r
+ x86_Convert_Init(x86State);\r
+ x86_Convert(filteredStream, srcLen, 0, &x86State, 1);\r
+ }\r
+ }\r
+\r
+ {\r
+ size_t minSize = 0;\r
+ BoolInt bestIsFiltered = False;\r
+\r
+ /* passes for SZ_FILTER_AUTO:\r
+ 0 - BCJ + LZMA\r
+ 1 - LZMA\r
+ 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.\r
+ */\r
+ int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;\r
+\r
+ int i;\r
+ for (i = 0; i < numPasses; i++)\r
+ {\r
+ size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;\r
+ size_t outPropsSize = 5;\r
+ SRes curRes;\r
+ BoolInt curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);\r
+ if (curModeIsFiltered && !bestIsFiltered)\r
+ break;\r
+ if (useFilter && i == 0)\r
+ curModeIsFiltered = True;\r
+ \r
+ curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,\r
+ curModeIsFiltered ? filteredStream : src, srcLen,\r
+ &props, dest + 1, &outPropsSize, 0,\r
+ NULL, &g_Alloc, &g_Alloc);\r
+ \r
+ if (curRes != SZ_ERROR_OUTPUT_EOF)\r
+ {\r
+ if (curRes != SZ_OK)\r
+ {\r
+ mainResult = curRes;\r
+ break;\r
+ }\r
+ if (outSizeProcessed <= minSize || mainResult != SZ_OK)\r
+ {\r
+ minSize = outSizeProcessed;\r
+ bestIsFiltered = curModeIsFiltered;\r
+ mainResult = SZ_OK;\r
+ }\r
+ }\r
+ }\r
+ dest[0] = (Byte)(bestIsFiltered ? 1 : 0);\r
+ *destLen = LZMA86_HEADER_SIZE + minSize;\r
+ }\r
+ if (useFilter)\r
+ MyFree(filteredStream);\r
+ return mainResult;\r
+}\r