forked from jrsoftware/issrc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
islzma.c
137 lines (115 loc) · 3.6 KB
/
islzma.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
islzma.c, by Jordan Russell for Inno Setup
This file is public domain (like the LZMA SDK)
$jrsoftware: issrc/Projects/lzma2/Encoder/islzma.c,v 1.7 2010/03/24 19:55:40 jr Exp $
*/
#include <stddef.h>
#include <windows.h>
#include "../C/Alloc.h"
#include "../C/LzmaEnc.h"
#include "../C/Lzma2Enc.h"
#include "islzma.h"
// Private definition of a handle; callers of the DLL should use void*
struct LZMAHandle {
int marker;
BOOL LZMA2;
CLzmaEncHandle encoder1;
CLzma2EncHandle encoder2;
};
#define LZMA_HANDLE_MARKER 0x3E1A981F
#define LZMA_HANDLE_VALID(h) ((h) && (h)->marker == LZMA_HANDLE_MARKER)
static void *SzBigAlloc(void *p, size_t size) { return BigAlloc(size); }
static void SzBigFree(void *p, void *address) { BigFree(address); }
static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
static void *SzAlloc(void *p, size_t size) { return MyAlloc(size); }
static void SzFree(void *p, void *address) { MyFree(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
SRes __stdcall LZMA_Init(BOOL LZMA2, struct LZMAHandle **handle)
{
struct LZMAHandle *h = calloc(1, sizeof(*h));
if (!h) return SZ_ERROR_MEM;
h->marker = LZMA_HANDLE_MARKER;
h->LZMA2 = LZMA2;
if (LZMA2) {
if (!(h->encoder2 = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc))) {
free(h);
return SZ_ERROR_MEM;
}
} else {
if (!(h->encoder1 = LzmaEnc_Create(&g_Alloc))) {
free(h);
return SZ_ERROR_MEM;
}
}
*handle = h;
return SZ_OK;
}
SRes __stdcall LZMA_SetProps(struct LZMAHandle *handle,
struct LZMAEncoderProps *encProps, size_t encPropsSize)
{
CLzmaEncProps props1;
CLzma2EncProps props2;
CLzmaEncProps *props;
if (!LZMA_HANDLE_VALID(handle) || encPropsSize != sizeof(*encProps)) {
return SZ_ERROR_PARAM;
}
if (handle->LZMA2) {
Lzma2EncProps_Init(&props2);
props = &props2.lzmaProps;
} else {
LzmaEncProps_Init(&props1);
props = &props1;
}
props->algo = encProps->Algorithm;
props->dictSize = encProps->DictionarySize;
props->fb = encProps->NumFastBytes;
props->btMode = encProps->BTMode;
props->numThreads = encProps->NumThreads;
if (handle->LZMA2) {
props2.numBlockThreads = encProps->NumBlockThreads;
props2.blockSize = encProps->BlockSize;
return Lzma2Enc_SetProps(handle->encoder2, &props2);
} else {
props1.writeEndMark = 1;
return LzmaEnc_SetProps(handle->encoder1, &props1);
}
}
SRes __stdcall LZMA_Encode(struct LZMAHandle *handle, ISeqInStream *inStream,
ISeqOutStream *outStream, ICompressProgress *progress)
{
if (!LZMA_HANDLE_VALID(handle)) return SZ_ERROR_PARAM;
if (handle->LZMA2) {
Byte props;
SizeT propsSize = sizeof(props);
props = Lzma2Enc_WriteProperties(handle->encoder2);
if (outStream->Write(outStream, &props, propsSize) != propsSize) {
return SZ_ERROR_WRITE;
};
return Lzma2Enc_Encode(handle->encoder2, outStream, inStream, progress);
} else {
Byte props[LZMA_PROPS_SIZE];
SizeT propsSize = sizeof(props);
RINOK(LzmaEnc_WriteProperties(handle->encoder1, props, &propsSize));
if (outStream->Write(outStream, &props, propsSize) != propsSize) {
return SZ_ERROR_WRITE;
};
return LzmaEnc_Encode(handle->encoder1, outStream, inStream, progress,
&g_Alloc, &g_BigAlloc);
}
}
SRes __stdcall LZMA_End(struct LZMAHandle *handle)
{
if (!LZMA_HANDLE_VALID(handle)) return SZ_ERROR_PARAM;
handle->marker = 0;
if (handle->LZMA2) {
if (handle->encoder2) {
Lzma2Enc_Destroy(handle->encoder2);
}
} else {
if (handle->encoder1) {
LzmaEnc_Destroy(handle->encoder1, &g_Alloc, &g_BigAlloc);
}
}
free(handle);
return SZ_OK;
}