+################################################################################
+# quick hack for using aplib (http://www.ibsensoftware.com/products_aPLib.html)
+# put aplib.dll in %PATH% or same dir as this script
+# on *nix it might require LD_LIBRARY_PATH set depending on where libaplib.so is
+# 20161001 - added 'dnh' option to decompress data with no aplib header - alexander hanel
+################################################################################
+__all__ = [ 'pack', 'pack_safe', 'depack', 'depack_safe', 'CB_COMPRESS']
+################################################################################
+ CB_COMPRESS = WINFUNCTYPE(c_uint, c_uint, c_uint, c_uint, c_void_p)
+ CB_COMPRESS = CFUNCTYPE(c_uint, c_uint, c_uint, c_uint, c_void_p)
+ # might require LD_LIBRARY_PATH set
+ _aplib = CDLL("libaplib.so")
+def _ratio(inpos, insize):
+ return (inpos * 100) / insize
+def _cbCompress(insize, inpos, outpos, cbparam):
+ print "compressed %u -> %u bytes (%u%% done)" % \
+ ( inpos, outpos, _ratio(inpos, insize))
+_cbCompressFunc = CB_COMPRESS(_cbCompress)
+################################################################################
+ raise ValueError('Invalid input.')
+ dstlen = _aplib.aP_max_packed_size(srclen)
+ dst = create_string_buffer(dstlen)
+ wrkmem = create_string_buffer(_aplib.aP_workmem_size(srclen))
+ dstlen = _aplib.aP_pack(src, dst, srclen, wrkmem, cb, 0)
+ raise ValueError('Compression error.')
+ return buffer(dst, 0, dstlen)
+def pack_safe(src, cb=None):
+ raise ValueError('Invalid input.')
+ dstlen = _aplib.aP_max_packed_size(srclen)
+ dst = create_string_buffer(dstlen)
+ wrkmem = create_string_buffer(_aplib.aP_workmem_size(srclen))
+ dstlen = _aplib.aPsafe_pack(src, dst, srclen, wrkmem, cb, 0)
+ raise ValueError('Compression error.')
+ return buffer(dst, 0, dstlen)
+################################################################################
+def depack(src, dstlen):
+ if srclen <= 0 or dstlen <= 0:
+ raise ValueError('Invalid input.')
+ dst = create_string_buffer(dstlen)
+ dstlen = _aplib.aP_depack_asm_safe(src, srclen, dst, dstlen)
+ raise ValueError('Decompression error.')
+ return buffer(dst, 0, dstlen)
+ raise ValueError('Invalid input.')
+ dstlen = _aplib.aPsafe_get_orig_size(src)
+ dst = create_string_buffer(dstlen)
+ dstlen = _aplib.aPsafe_depack(src, srclen, dst, dstlen)
+ raise ValueError('Decompression error.')
+ return buffer(dst, 0, dstlen)
+def depack_no_header(src):
+ # uses aP_depack_asm_fast to decompress buffer
+ # probably could allocate less but don't really care
+ if srclen <= 0 or dstlen <= 0:
+ raise ValueError('Invalid input.')
+ dst = create_string_buffer(dstlen)
+ dstlen = _aplib.aP_depack_asm_fast(src, dst)
+ raise ValueError('Decompression error.')
+ return buffer(dst, 0, dstlen)
+################################################################################
+if __name__ == "__main__":
+ parser = optparse.OptionParser(
+ usage='%prog [-h] [-v] -m c|d infile outfile'
+ help='c for compress, d for decompress')
+ options, args = parser.parse_args()
+ if not options.mode in ['c', 'd', 'dnh']:
+ parser.error('You must give a valid --mode')
+ parser.error('You must give in- and outfile')
+ src = open(infile, 'rb').read()
+ if options.mode == 'c':
+ print "Compressing '%s' to '%s'" % (infile, outfile)
+ dst = pack_safe(src, _cbCompressFunc)
+ open(outfile, 'wb').write(dst)
+ print "Compressed '%s' from %u to %u bytes (%u%%)" \
+ % (infile, len(src), len(dst), _ratio(len(dst), len(src)))
+ elif options.mode == 'd':
+ print "Decompressing '%s' to '%s'" % (infile, outfile)
+ open(outfile, 'wb').write(dst)
+ print "Decompressed '%s' from %u to %u bytes (%u%%)" \
+ % (infile, len(src), len(dst), _ratio(len(dst), len(src)))
+ elif options.mode == 'dnh':
+ print "Decompressing '%s' to '%s'" % (infile, outfile)
+ dst = depack_no_header(src)
+ open(outfile, 'wb').write(dst)
+ print "Decompressed '%s' from %u to %u bytes (%u%%)" \
+ % (infile, len(src), len(dst), _ratio(len(dst), len(src)))
+################################################################################