src/third-party/lzma/Lzma86Enc.c (view raw)
1/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
22015-11-08 : 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#define SZE_OUT_OVERFLOW SZE_DATA_ERROR
15
16static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
17static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
18
19int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
20 int level, UInt32 dictSize, int filterMode)
21{
22 ISzAlloc g_Alloc = { SzAlloc, SzFree };
23 size_t outSize2 = *destLen;
24 Byte *filteredStream;
25 Bool useFilter;
26 int mainResult = SZ_ERROR_OUTPUT_EOF;
27 CLzmaEncProps props;
28 LzmaEncProps_Init(&props);
29 props.level = level;
30 props.dictSize = dictSize;
31
32 *destLen = 0;
33 if (outSize2 < LZMA86_HEADER_SIZE)
34 return SZ_ERROR_OUTPUT_EOF;
35
36 {
37 int i;
38 UInt64 t = srcLen;
39 for (i = 0; i < 8; i++, t >>= 8)
40 dest[LZMA86_SIZE_OFFSET + i] = (Byte)t;
41 }
42
43 filteredStream = 0;
44 useFilter = (filterMode != SZ_FILTER_NO);
45 if (useFilter)
46 {
47 if (srcLen != 0)
48 {
49 filteredStream = (Byte *)MyAlloc(srcLen);
50 if (filteredStream == 0)
51 return SZ_ERROR_MEM;
52 memcpy(filteredStream, src, srcLen);
53 }
54 {
55 UInt32 x86State;
56 x86_Convert_Init(x86State);
57 x86_Convert(filteredStream, srcLen, 0, &x86State, 1);
58 }
59 }
60
61 {
62 size_t minSize = 0;
63 Bool bestIsFiltered = False;
64
65 /* passes for SZ_FILTER_AUTO:
66 0 - BCJ + LZMA
67 1 - LZMA
68 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
69 */
70 int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
71
72 int i;
73 for (i = 0; i < numPasses; i++)
74 {
75 size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;
76 size_t outPropsSize = 5;
77 SRes curRes;
78 Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);
79 if (curModeIsFiltered && !bestIsFiltered)
80 break;
81 if (useFilter && i == 0)
82 curModeIsFiltered = True;
83
84 curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,
85 curModeIsFiltered ? filteredStream : src, srcLen,
86 &props, dest + 1, &outPropsSize, 0,
87 NULL, &g_Alloc, &g_Alloc);
88
89 if (curRes != SZ_ERROR_OUTPUT_EOF)
90 {
91 if (curRes != SZ_OK)
92 {
93 mainResult = curRes;
94 break;
95 }
96 if (outSizeProcessed <= minSize || mainResult != SZ_OK)
97 {
98 minSize = outSizeProcessed;
99 bestIsFiltered = curModeIsFiltered;
100 mainResult = SZ_OK;
101 }
102 }
103 }
104 dest[0] = (Byte)(bestIsFiltered ? 1 : 0);
105 *destLen = LZMA86_HEADER_SIZE + minSize;
106 }
107 if (useFilter)
108 MyFree(filteredStream);
109 return mainResult;
110}