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/>.
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 */
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
;
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 // ////////////////////////////////////////////////////////////////////////// //
55 SZ_ERROR_UNSUPPORTED
= 4,
57 SZ_ERROR_INPUT_EOF
= 6,
58 SZ_ERROR_OUTPUT_EOF
= 7,
61 SZ_ERROR_PROGRESS
= 10,
70 /* The following interfaces use first parameter as pointer to structure */
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
*;
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)
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:
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 // ////////////////////////////////////////////////////////////////////////// //
183 alias CLzmaProb
= ushort;
186 /* ---------- LZMA Properties ---------- */
196 /* LzmaProps_Decode - decodes properties
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;
213 /* Don't change this structure. ASM code can use it. */
216 CLzmaProb
* probs_1664
;
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;
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;
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
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:
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.
313 for (each new stream)
316 while (it needs more decompression)
318 LzmaDec_DecodeToDic()
319 use data from CLzmaDec::dic and update CLzmaDec::dicPos
325 /* LzmaDec_DecodeToDic
327 The decoding to internal dictionary buffer (CLzmaDec::dic).
328 You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
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.
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.
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 ---------- */
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).
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
);