egra: even more comments
[iv.d.git] / c / lzma.d
bloba8bea5b6223b5546a3dde5c11016b25a6db816d4
1 /* converted by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
2 * Understanding is not required. Only obedience.
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, version 3 of the License ONLY.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 module iv.c.lzma;
17 pragma(lib, "clzma");
19 extern (C) __gshared nothrow:
21 /* LZMA_PROB32 can increase the speed on some CPUs,
22 but memory usage for CLzmaDec::probs will be doubled in that case */
23 //#define LZMA_PROB32
25 /* use smaller (by ~3KB), but slightly slower (prolly) decompression code? */
26 //#define LZMA_SIZE_OPT
28 /* use slightly smaller (around 300 bytes) code with branching in compressor? */
29 //#define LZMA_ENC_USE_BRANCH
32 // ////////////////////////////////////////////////////////////////////////// //
33 static void *lzmaMMAlloc (ISzAllocPtr p, usize size) {
34 import core.stdc.stdlib : malloc;
35 size += !size;
36 return malloc(size);
39 /* address can be 0 */
40 static void lzmaMMFree (ISzAllocPtr p, void* address) {
41 import core.stdc.stdlib : free;
42 if (address !is null) free(address);
45 __gshared ISzAlloc lzmaDefAllocator = ISzAlloc(&lzmaMMAlloc, &lzmaMMFree);
48 // ////////////////////////////////////////////////////////////////////////// //
49 enum {
50 SZ_OK = 0,
52 SZ_ERROR_DATA = 1,
53 SZ_ERROR_MEM = 2,
54 // SZ_ERROR_CRC = 3,
55 SZ_ERROR_UNSUPPORTED = 4,
56 SZ_ERROR_PARAM = 5,
57 SZ_ERROR_INPUT_EOF = 6,
58 SZ_ERROR_OUTPUT_EOF = 7,
59 SZ_ERROR_READ = 8,
60 SZ_ERROR_WRITE = 9,
61 SZ_ERROR_PROGRESS = 10,
62 SZ_ERROR_FAIL = 11,
66 alias SRes = int;
67 alias WRes = int;
70 /* The following interfaces use first parameter as pointer to structure */
72 struct ISeqInStream {
73 SRes function (/*const*/ISeqInStream* p, void* buf, usize* size) Read;
74 /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
75 (output(*size) < input(*size)) is allowed */
77 //#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
80 struct ISeqOutStream {
81 usize function (/*const*/ISeqOutStream* p, const(void)* buf, usize size) nothrow Write;
82 /* Returns: result - the number of actually written bytes.
83 (result < size) means error */
85 //#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
88 struct ICompressProgress {
89 SRes function (/*const*/ICompressProgress* p, ulong inSize, ulong outSize) nothrow Progress;
90 /* Returns: result. (result != SZ_OK) means break.
91 Value (ulong)(long)-1 for size means unknown value. */
93 //#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
96 alias ISzAllocPtr = ISzAlloc*;
97 struct ISzAlloc {
98 void *function (ISzAllocPtr p, usize size) nothrow Alloc;
99 void function (ISzAllocPtr p, void *address) nothrow Free; /* address can be 0 */
102 //#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
103 //#define ISzAlloc_Free(p, a) (p)->Free(p, a)
105 /* deprecated */
106 //#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
107 //#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
110 // ////////////////////////////////////////////////////////////////////////// //
111 enum LZMA_PROPS_SIZE = 5;
113 struct CLzmaEncProps {
114 int level; /* 0 <= level <= 9 */
115 uint dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
116 (1 << 12) <= dictSize <= (3 << 29) for 64-bit version
117 default = (1 << 24) */
118 int lc; /* 0 <= lc <= 8, default = 3 */
119 int lp; /* 0 <= lp <= 4, default = 0 */
120 int pb; /* 0 <= pb <= 4, default = 2 */
121 int algo; /* 0 - fast, 1 - normal, default = 1 */
122 int fb; /* 5 <= fb <= 273, default = 32 */
123 int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
124 int numHashBytes; /* 2, 3 or 4, default = 4 */
125 uint mc; /* 1 <= mc <= (1 << 30), default = 32 */
126 uint writeEndMark;/* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
128 ulong reduceSize; /* estimated size of data that will be compressed. default = (ulong)(long)-1.
129 Encoder uses this value to reduce dictionary size */
132 void LzmaEncProps_Init (CLzmaEncProps *p) @nogc;
133 void LzmaEncProps_Normalize (CLzmaEncProps *p) @nogc;
134 uint LzmaEncProps_GetDictSize (const(CLzmaEncProps)* props2) @nogc;
137 /* ---------- CLzmaEncHandle Interface ---------- */
139 /* LzmaEnc* functions can return the following exit codes:
140 SRes:
141 SZ_OK - OK
142 SZ_ERROR_MEM - Memory allocation error
143 SZ_ERROR_PARAM - Incorrect paramater in props
144 SZ_ERROR_WRITE - ISeqOutStream write callback error
145 SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (ubyte *) output
146 SZ_ERROR_PROGRESS - some break from progress callback
149 alias CLzmaEncHandle = void*;
151 CLzmaEncHandle LzmaEnc_Create (ISzAllocPtr alloc);
152 void LzmaEnc_Destroy (CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig);
154 SRes LzmaEnc_SetProps (CLzmaEncHandle p, const(CLzmaEncProps)* props) @nogc;
155 void LzmaEnc_SetDataSize (CLzmaEncHandle p, ulong expectedDataSiize) @nogc;
156 SRes LzmaEnc_WriteProperties (CLzmaEncHandle p, ubyte* properties, usize* size) @nogc;
157 uint LzmaEnc_IsWriteEndMark (CLzmaEncHandle p) @nogc;
159 SRes LzmaEnc_Encode (CLzmaEncHandle p, ISeqOutStream* outStream, ISeqInStream* inStream,
160 ICompressProgress* progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
162 SRes LzmaEnc_MemEncode (CLzmaEncHandle p, void* dest, usize* destLen, const(void)* src, usize srcLen,
163 int writeEndMark, ICompressProgress* progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
166 /* ---------- One Call Interface ---------- */
168 SRes LzmaEncode (void* dest, usize* destLen, const(void)* src, usize srcLen,
169 const(CLzmaEncProps)* props, ubyte* propsEncoded, usize* propsSize,
170 int writeEndMark, ICompressProgress* progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
173 // ////////////////////////////////////////////////////////////////////////// //
175 typedef
176 #ifdef LZMA_PROB32
177 uint
178 #else
179 uint16_t
180 #endif
181 CLzmaProb;
183 alias CLzmaProb = ushort;
186 /* ---------- LZMA Properties ---------- */
188 struct CLzmaProps {
189 ubyte lc;
190 ubyte lp;
191 ubyte pb;
192 ubyte _pad_;
193 uint dicSize;
196 /* LzmaProps_Decode - decodes properties
197 Returns:
198 SZ_OK
199 SZ_ERROR_UNSUPPORTED - Unsupported properties
202 SRes LzmaProps_Decode (CLzmaProps* p, const(void)* data, uint size) @nogc;
205 /* ---------- LZMA Decoder state ---------- */
207 /* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
208 Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
210 enum LZMA_REQUIRED_INPUT_MAX = 20;
212 struct CLzmaDec {
213 /* Don't change this structure. ASM code can use it. */
214 CLzmaProps prop;
215 CLzmaProb* probs;
216 CLzmaProb* probs_1664;
217 ubyte* dic;
218 usize dicBufSize;
219 usize dicPos;
220 const(ubyte)* buf;
221 uint range;
222 uint code;
223 uint processedPos;
224 uint checkDicSize;
225 uint[4] reps;
226 uint state;
227 uint remainLen;
229 uint numProbs;
230 uint tempBufSize;
231 ubyte[LZMA_REQUIRED_INPUT_MAX] tempBuf;
234 //#define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; }
235 void LzmaDec_Construct (CLzmaDec* p) @nogc { pragma(inline, true); if (p) { p.dic = null; p.probs = null; } }
237 void LzmaDec_Init (CLzmaDec* p) @nogc;
239 /* There are two types of LZMA streams:
240 - Stream with end mark. That end mark adds about 6 bytes to compressed size.
241 - Stream without end mark. You must know exact uncompressed size to decompress such stream. */
243 alias ELzmaFinishMode = int;
244 enum {
245 LZMA_FINISH_ANY, /* finish at any point */
246 LZMA_FINISH_END, /* block must be finished at the end */
249 /* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
251 You must use LZMA_FINISH_END, when you know that current output buffer
252 covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
254 If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
255 and output value of destLen will be less than output buffer size limit.
256 You can check status result also.
258 You can use multiple checks to test data integrity after full decompression:
259 1) Check Result and "status" variable.
260 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
261 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
262 You must use correct finish mode in that case. */
264 alias ELzmaStatus = int;
265 enum {
266 LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
267 LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
268 LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
269 LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
270 LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK, /* there is probability that stream was finished without end mark */
273 /* ELzmaStatus is used only as output value for function call */
276 /* ---------- Interfaces ---------- */
278 /* There are 3 levels of interfaces:
279 1) Dictionary Interface
280 2) Buffer Interface
281 3) One Call Interface
282 You can select any of these interfaces, but don't mix functions from different
283 groups for same object. */
286 /* There are two variants to allocate state for Dictionary Interface:
287 1) LzmaDec_Allocate / LzmaDec_Free
288 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
289 You can use variant 2, if you set dictionary buffer manually.
290 For Buffer Interface you must always use variant 1.
292 LzmaDec_Allocate* can return:
293 SZ_OK
294 SZ_ERROR_MEM - Memory allocation error
295 SZ_ERROR_UNSUPPORTED - Unsupported properties
298 SRes LzmaDec_AllocateProbs (CLzmaDec* p, const(void)* props, uint propsSize, ISzAllocPtr alloc);
299 void LzmaDec_FreeProbs (CLzmaDec* p, ISzAllocPtr alloc);
301 SRes LzmaDec_Allocate (CLzmaDec* p, const(void)* props, uint propsSize, ISzAllocPtr alloc);
302 void LzmaDec_Free (CLzmaDec* p, ISzAllocPtr alloc);
304 /* ---------- Dictionary Interface ---------- */
306 /* You can use it, if you want to eliminate the overhead for data copying from
307 dictionary to some other external buffer.
308 You must work with CLzmaDec variables directly in this interface.
310 STEPS:
311 LzmaDec_Construct()
312 LzmaDec_Allocate()
313 for (each new stream)
315 LzmaDec_Init()
316 while (it needs more decompression)
318 LzmaDec_DecodeToDic()
319 use data from CLzmaDec::dic and update CLzmaDec::dicPos
322 LzmaDec_Free()
325 /* LzmaDec_DecodeToDic
327 The decoding to internal dictionary buffer (CLzmaDec::dic).
328 You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
330 finishMode:
331 It has meaning only if the decoding reaches output limit (dicLimit).
332 LZMA_FINISH_ANY - Decode just dicLimit bytes.
333 LZMA_FINISH_END - Stream must be finished after dicLimit.
335 Returns:
336 SZ_OK
337 status:
338 LZMA_STATUS_FINISHED_WITH_MARK
339 LZMA_STATUS_NOT_FINISHED
340 LZMA_STATUS_NEEDS_MORE_INPUT
341 LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
342 SZ_ERROR_DATA - Data error
343 SZ_ERROR_FAIL - Some unexpected error: internal error of code, memory corruption or hardware failure
346 SRes LzmaDec_DecodeToDic (CLzmaDec* p, usize dicLimit,
347 const(void)* src, usize* srcLen,
348 ELzmaFinishMode finishMode, ELzmaStatus* status) @nogc;
351 /* ---------- Buffer Interface ---------- */
353 /* It's zlib-like interface.
354 See LzmaDec_DecodeToDic description for information about STEPS and return results,
355 but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
356 to work with CLzmaDec variables manually.
358 finishMode:
359 It has meaning only if the decoding reaches output limit (*destLen).
360 LZMA_FINISH_ANY - Decode just destLen bytes.
361 LZMA_FINISH_END - Stream must be finished after (*destLen).
364 SRes LzmaDec_DecodeToBuf (CLzmaDec* p, void* dest, usize* destLen,
365 const(void)* src, usize* srcLen,
366 ELzmaFinishMode finishMode, ELzmaStatus* status) @nogc;
369 /* ---------- One Call Interface ---------- */
371 /* LzmaDecode
373 finishMode:
374 It has meaning only if the decoding reaches output limit (*destLen).
375 LZMA_FINISH_ANY - Decode just destLen bytes.
376 LZMA_FINISH_END - Stream must be finished after (*destLen).
378 Returns:
379 SZ_OK
380 status:
381 LZMA_STATUS_FINISHED_WITH_MARK
382 LZMA_STATUS_NOT_FINISHED
383 LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
384 SZ_ERROR_DATA - Data error
385 SZ_ERROR_MEM - Memory allocation error
386 SZ_ERROR_UNSUPPORTED - Unsupported properties
387 SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
388 SZ_ERROR_FAIL - Some unexpected error: internal error of code, memory corruption or hardware failure
391 SRes LzmaDecode (void* dest, usize* destLen, const(void)* src, usize* srcLen,
392 const(void)* propData, uint propSize,
393 ELzmaFinishMode finishMode, ELzmaStatus* status, ISzAllocPtr alloc);