Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/lzma/src/Lzma86Enc.c
4253 views
1
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
2
2023-03-03 : 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
14
int 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 = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL;
50
z7_BranchConvSt_X86_Enc(filteredStream, srcLen, 0, &x86State);
51
}
52
}
53
54
{
55
size_t minSize = 0;
56
BoolInt bestIsFiltered = False;
57
58
/* passes for SZ_FILTER_AUTO:
59
0 - BCJ + LZMA
60
1 - LZMA
61
2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
62
*/
63
int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
64
65
int i;
66
for (i = 0; i < numPasses; i++)
67
{
68
size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;
69
size_t outPropsSize = 5;
70
SRes curRes;
71
BoolInt curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);
72
if (curModeIsFiltered && !bestIsFiltered)
73
break;
74
if (useFilter && i == 0)
75
curModeIsFiltered = True;
76
77
curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,
78
curModeIsFiltered ? filteredStream : src, srcLen,
79
&props, dest + 1, &outPropsSize, 0,
80
NULL, &g_Alloc, &g_Alloc);
81
82
if (curRes != SZ_ERROR_OUTPUT_EOF)
83
{
84
if (curRes != SZ_OK)
85
{
86
mainResult = curRes;
87
break;
88
}
89
if (outSizeProcessed <= minSize || mainResult != SZ_OK)
90
{
91
minSize = outSizeProcessed;
92
bestIsFiltered = curModeIsFiltered;
93
mainResult = SZ_OK;
94
}
95
}
96
}
97
dest[0] = (Byte)(bestIsFiltered ? 1 : 0);
98
*destLen = LZMA86_HEADER_SIZE + minSize;
99
}
100
if (useFilter)
101
MyFree(filteredStream);
102
return mainResult;
103
}
104
105