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 }