aboutsummaryrefslogtreecommitdiff
path: root/C/Lzma86Enc.c
diff options
context:
space:
mode:
authorIgor Pavlov <87184205+ip7z@users.noreply.github.com>2021-12-27 00:00:00 +0000
committerIgor Pavlov <87184205+ip7z@users.noreply.github.com>2022-03-18 15:35:13 +0500
commitf19f813537c7aea1c20749c914e756b54a9c3cf5 (patch)
tree816ba62ca7c0fa19f2eb46d9e9d6f7dd7c3a744d /C/Lzma86Enc.c
parent98e06a519b63b81986abe76d28887f6984a7732b (diff)
download7zip-21.07.tar.gz
7zip-21.07.tar.bz2
7zip-21.07.zip
'21.07'21.07
Diffstat (limited to 'C/Lzma86Enc.c')
-rw-r--r--C/Lzma86Enc.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/C/Lzma86Enc.c b/C/Lzma86Enc.c
new file mode 100644
index 0000000..14fcd65
--- /dev/null
+++ b/C/Lzma86Enc.c
@@ -0,0 +1,104 @@
1/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
22018-07-04 : Igor Pavlov : Public domain */
3
4#include "Precomp.h"
5
6#include <string.h>
7
8#include "Lzma86.h"
9
10#include "Alloc.h"
11#include "Bra.h"
12#include "LzmaEnc.h"
13
14int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
15 int level, UInt32 dictSize, int filterMode)
16{
17 size_t outSize2 = *destLen;
18 Byte *filteredStream;
19 BoolInt useFilter;
20 int mainResult = SZ_ERROR_OUTPUT_EOF;
21 CLzmaEncProps props;
22 LzmaEncProps_Init(&props);
23 props.level = level;
24 props.dictSize = dictSize;
25
26 *destLen = 0;
27 if (outSize2 < LZMA86_HEADER_SIZE)
28 return SZ_ERROR_OUTPUT_EOF;
29
30 {
31 int i;
32 UInt64 t = srcLen;
33 for (i = 0; i < 8; i++, t >>= 8)
34 dest[LZMA86_SIZE_OFFSET + i] = (Byte)t;
35 }
36
37 filteredStream = 0;
38 useFilter = (filterMode != SZ_FILTER_NO);
39 if (useFilter)
40 {
41 if (srcLen != 0)
42 {
43 filteredStream = (Byte *)MyAlloc(srcLen);
44 if (filteredStream == 0)
45 return SZ_ERROR_MEM;
46 memcpy(filteredStream, src, srcLen);
47 }
48 {
49 UInt32 x86State;
50 x86_Convert_Init(x86State);
51 x86_Convert(filteredStream, srcLen, 0, &x86State, 1);
52 }
53 }
54
55 {
56 size_t minSize = 0;
57 BoolInt bestIsFiltered = False;
58
59 /* passes for SZ_FILTER_AUTO:
60 0 - BCJ + LZMA
61 1 - LZMA
62 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
63 */
64 int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
65
66 int i;
67 for (i = 0; i < numPasses; i++)
68 {
69 size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;
70 size_t outPropsSize = 5;
71 SRes curRes;
72 BoolInt curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);
73 if (curModeIsFiltered && !bestIsFiltered)
74 break;
75 if (useFilter && i == 0)
76 curModeIsFiltered = True;
77
78 curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,
79 curModeIsFiltered ? filteredStream : src, srcLen,
80 &props, dest + 1, &outPropsSize, 0,
81 NULL, &g_Alloc, &g_Alloc);
82
83 if (curRes != SZ_ERROR_OUTPUT_EOF)
84 {
85 if (curRes != SZ_OK)
86 {
87 mainResult = curRes;
88 break;
89 }
90 if (outSizeProcessed <= minSize || mainResult != SZ_OK)
91 {
92 minSize = outSizeProcessed;
93 bestIsFiltered = curModeIsFiltered;
94 mainResult = SZ_OK;
95 }
96 }
97 }
98 dest[0] = (Byte)(bestIsFiltered ? 1 : 0);
99 *destLen = LZMA86_HEADER_SIZE + minSize;
100 }
101 if (useFilter)
102 MyFree(filteredStream);
103 return mainResult;
104}