1 module zgrf.compression;
2 
3 import lzma;
4 
5 extern (C) private void* szAlloc(void* p, size_t size)
6 {
7     import core.stdc.stdlib : malloc;
8 
9     return malloc(size);
10 }
11 
12 extern (C) private void szFree(void* p, void* address)
13 {
14     import core.stdc.stdlib : free;
15 
16     free(address);
17 }
18 
19 private ISzAlloc szAllocLzma = {&szAlloc, &szFree};
20 
21 /**
22  * Uncompresses data. If the first byte of srcbuf is 0 then
23  * LZMA will be used to uncompress the data. Otherwise
24  * uses zlib.
25  *
26  * Params:
27  *  srcbuf = The compressed data
28  *  destlen = The uncompressed size
29  *
30  * Returns:
31  *  The uncompressed data
32  */
33 ubyte[] uncompress(const(ubyte)[] srcbuf, size_t destlen = 0u)
34 {
35     ubyte[] dst;
36     if (destlen == 0)
37     {
38         destlen = srcbuf.length * 2 + 1;
39     }
40 
41     if (srcbuf[0] == 0)
42     {
43         if (srcbuf.length < LZMA_PROPS_SIZE + 1)
44         {
45             return dst;
46         }
47         ELzmaStatus status;
48         SizeT destlen2 = destlen;
49         SizeT pack_size = srcbuf.length - LZMA_PROPS_SIZE - 1;
50         dst = new ubyte[destlen];
51         int ret = LzmaDecode(
52                 dst.ptr,
53                 &destlen2,
54                 cast(const(Byte*))(&srcbuf[LZMA_PROPS_SIZE + 1]),
55                 &pack_size,
56                 cast(const(Byte*))(&srcbuf[1]),
57                 LZMA_PROPS_SIZE,
58                 ELzmaFinishMode.LZMA_FINISH_END,
59                 &status,
60                 &szAllocLzma
61         );
62         if (ret != SZ_OK)
63         {
64         }
65     }
66     else
67     {
68         import std.zlib : zlib_uncompress = uncompress;
69 
70         dst = cast(ubyte[]) zlib_uncompress(srcbuf, destlen);
71     }
72     return dst;
73 }