summaryrefslogtreecommitdiffstats
path: root/depends/lzma/wrapper
diff options
context:
space:
mode:
Diffstat (limited to 'depends/lzma/wrapper')
-rw-r--r--depends/lzma/wrapper/common_internal.c46
-rw-r--r--depends/lzma/wrapper/common_internal.h60
-rw-r--r--depends/lzma/wrapper/compress.c297
-rw-r--r--depends/lzma/wrapper/decompress.c263
-rw-r--r--depends/lzma/wrapper/lzip_header.c96
-rw-r--r--depends/lzma/wrapper/lzip_header.h11
-rw-r--r--depends/lzma/wrapper/lzma_header.c134
-rw-r--r--depends/lzma/wrapper/lzma_header.h10
-rw-r--r--depends/lzma/wrapper/simple.c139
9 files changed, 1056 insertions, 0 deletions
diff --git a/depends/lzma/wrapper/common_internal.c b/depends/lzma/wrapper/common_internal.c
new file mode 100644
index 00000000..c9213ef4
--- /dev/null
+++ b/depends/lzma/wrapper/common_internal.c
@@ -0,0 +1,46 @@
+/*
+ * Written in 2009 by Lloyd Hilaiel
+ *
+ * License
+ *
+ * All the cruft you find here is public domain. You don't have to credit
+ * anyone to use this code, but my personal request is that you mention
+ * Igor Pavlov for his hard, high quality work.
+ */
+
+#include "common_internal.h"
+
+static void *elzmaAlloc(void *p, size_t size)
+{
+ struct elzma_alloc_struct *as = (struct elzma_alloc_struct *)p;
+ if (as->clientMallocFunc)
+ {
+ return as->clientMallocFunc(as->clientMallocContext, size);
+ }
+ return malloc(size);
+}
+
+static void elzmaFree(void *p, void *address)
+{
+ struct elzma_alloc_struct *as = (struct elzma_alloc_struct *)p;
+ if (as->clientFreeFunc)
+ {
+ as->clientFreeFunc(as->clientMallocContext, address);
+ }
+ else
+ {
+ free(address);
+ }
+}
+
+void init_alloc_struct(struct elzma_alloc_struct *as, elzma_malloc clientMallocFunc,
+ void *clientMallocContext, elzma_free clientFreeFunc,
+ void *clientFreeContext)
+{
+ as->Alloc = elzmaAlloc;
+ as->Free = elzmaFree;
+ as->clientMallocFunc = clientMallocFunc;
+ as->clientMallocContext = clientMallocContext;
+ as->clientFreeFunc = clientFreeFunc;
+ as->clientFreeContext = clientFreeContext;
+}
diff --git a/depends/lzma/wrapper/common_internal.h b/depends/lzma/wrapper/common_internal.h
new file mode 100644
index 00000000..2c46fadf
--- /dev/null
+++ b/depends/lzma/wrapper/common_internal.h
@@ -0,0 +1,60 @@
+#ifndef __ELZMA_COMMON_INTERNAL_H__
+#define __ELZMA_COMMON_INTERNAL_H__
+
+#include "common.h"
+
+/** a structure which may be cast and passed into Igor's allocate
+ * routines */
+struct elzma_alloc_struct
+{
+ void *(*Alloc)(void *p, size_t size);
+ void (*Free)(void *p, void *address); /* address can be 0 */
+
+ elzma_malloc clientMallocFunc;
+ void *clientMallocContext;
+
+ elzma_free clientFreeFunc;
+ void *clientFreeContext;
+};
+
+/* initialize an allocation structure, may be called safely multiple
+ * times */
+void init_alloc_struct(struct elzma_alloc_struct *allocStruct, elzma_malloc clientMallocFunc,
+ void *clientMallocContext, elzma_free clientFreeFunc,
+ void *clientFreeContext);
+
+/** superset representation of a compressed file header */
+struct elzma_file_header
+{
+ unsigned char pb;
+ unsigned char lp;
+ unsigned char lc;
+ unsigned char isStreamed;
+ long long unsigned int uncompressedSize;
+ unsigned int dictSize;
+};
+
+/** superset representation of a compressed file footer */
+struct elzma_file_footer
+{
+ unsigned int crc32;
+ long long unsigned int uncompressedSize;
+};
+
+/** a structure which encapsulates information about the particular
+ * file header and footer in use (lzip vs lzma vs (eventually) xz.
+ * The intention of this structure is to simplify compression and
+ * decompression logic by abstracting the file format details a bit. */
+struct elzma_format_handler
+{
+ unsigned int header_size;
+ void (*init_header)(struct elzma_file_header *hdr);
+ int (*parse_header)(const unsigned char *hdrBuf, struct elzma_file_header *hdr);
+ int (*serialize_header)(unsigned char *hdrBuf, const struct elzma_file_header *hdr);
+
+ unsigned int footer_size;
+ int (*serialize_footer)(struct elzma_file_footer *ftr, unsigned char *ftrBuf);
+ int (*parse_footer)(const unsigned char *ftrBuf, struct elzma_file_footer *ftr);
+};
+
+#endif
diff --git a/depends/lzma/wrapper/compress.c b/depends/lzma/wrapper/compress.c
new file mode 100644
index 00000000..38ca0a68
--- /dev/null
+++ b/depends/lzma/wrapper/compress.c
@@ -0,0 +1,297 @@
+/*
+ * Written in 2009 by Lloyd Hilaiel
+ *
+ * License
+ *
+ * All the cruft you find here is public domain. You don't have to credit
+ * anyone to use this code, but my personal request is that you mention
+ * Igor Pavlov for his hard, high quality work.
+ */
+
+#include "compress.h"
+#include "lzma_header.h"
+#include "lzip_header.h"
+#include "common_internal.h"
+
+#include "pavlov/Types.h"
+#include "pavlov/LzmaEnc.h"
+#include "pavlov/7zCrc.h"
+
+#include <string.h>
+
+struct _elzma_compress_handle
+{
+ CLzmaEncProps props;
+ CLzmaEncHandle encHand;
+ unsigned long long uncompressedSize;
+ elzma_file_format format;
+ struct elzma_alloc_struct allocStruct;
+ struct elzma_format_handler formatHandler;
+};
+
+elzma_compress_handle elzma_compress_alloc()
+{
+ elzma_compress_handle hand = malloc(sizeof(struct _elzma_compress_handle));
+ memset((void *)hand, 0, sizeof(struct _elzma_compress_handle));
+
+ /* "reasonable" defaults for props */
+ LzmaEncProps_Init(&(hand->props));
+ hand->props.lc = 3;
+ hand->props.lp = 0;
+ hand->props.pb = 2;
+ hand->props.level = 5;
+ hand->props.algo = 1;
+ hand->props.fb = 32;
+ hand->props.dictSize = 1 << 24;
+ hand->props.btMode = 1;
+ hand->props.numHashBytes = 4;
+ hand->props.mc = 32;
+ hand->props.numThreads = 1;
+ hand->props.writeEndMark = 1;
+
+ init_alloc_struct(&(hand->allocStruct), NULL, NULL, NULL, NULL);
+
+ /* default format is LZMA-Alone */
+ initializeLZMAFormatHandler(&(hand->formatHandler));
+
+ return hand;
+}
+
+void elzma_compress_free(elzma_compress_handle *hand)
+{
+ if (hand && *hand)
+ {
+ if ((*hand)->encHand)
+ {
+ LzmaEnc_Destroy((*hand)->encHand);
+ }
+ }
+ *hand = NULL;
+}
+
+int elzma_compress_config(elzma_compress_handle hand, unsigned char lc, unsigned char lp,
+ unsigned char pb, unsigned char level, unsigned int dictionarySize,
+ elzma_file_format format, unsigned long long uncompressedSize)
+{
+ /* XXX: validate arguments are in valid ranges */
+
+ hand->props.lc = lc;
+ hand->props.lp = lp;
+ hand->props.pb = pb;
+ hand->props.level = level;
+ hand->props.dictSize = dictionarySize;
+ hand->uncompressedSize = uncompressedSize;
+ hand->format = format;
+
+ /* default of LZMA-Alone is set at alloc time, and there are only
+ * two possible formats */
+ if (format == ELZMA_lzip)
+ {
+ initializeLZIPFormatHandler(&(hand->formatHandler));
+ }
+
+ return ELZMA_E_OK;
+}
+
+/* use Igor's stream hooks for compression. */
+struct elzmaInStream
+{
+ SRes (*ReadPtr)(void *p, void *buf, size_t *size);
+ elzma_read_callback inputStream;
+ void *inputContext;
+ unsigned int crc32;
+ unsigned int crc32a;
+ unsigned int crc32b;
+ unsigned int crc32c;
+ int calculateCRC;
+};
+
+static SRes elzmaReadFunc(void *p, void *buf, size_t *size)
+{
+ int rv;
+ struct elzmaInStream *is = (struct elzmaInStream *)p;
+ rv = is->inputStream(is->inputContext, buf, size);
+ if (rv == 0 && *size > 0 && is->calculateCRC)
+ {
+ is->crc32 = CrcUpdate(is->crc32, buf, *size);
+ }
+ return rv;
+}
+
+struct elzmaOutStream
+{
+ size_t (*WritePtr)(void *p, const void *buf, size_t size);
+ elzma_write_callback outputStream;
+ void *outputContext;
+};
+
+static size_t elzmaWriteFunc(void *p, const void *buf, size_t size)
+{
+ struct elzmaOutStream *os = (struct elzmaOutStream *)p;
+ return os->outputStream(os->outputContext, buf, size);
+}
+
+/* use Igor's stream hooks for compression. */
+struct elzmaProgressStruct
+{
+ SRes (*Progress)(void *p, uint64_t inSize, uint64_t outSize);
+ long long unsigned int uncompressedSize;
+ elzma_progress_callback progressCallback;
+ void *progressContext;
+};
+
+#include <stdio.h>
+static SRes elzmaProgress(void *p, uint64_t inSize, uint64_t outSize)
+{
+ struct elzmaProgressStruct *ps = (struct elzmaProgressStruct *)p;
+ if (ps->progressCallback)
+ {
+ ps->progressCallback(ps->progressContext, inSize, ps->uncompressedSize);
+ }
+ return SZ_OK;
+}
+
+void elzma_compress_set_allocation_callbacks(elzma_compress_handle hand,
+ elzma_malloc mallocFunc, void *mallocFuncContext,
+ elzma_free freeFunc, void *freeFuncContext)
+{
+ if (hand)
+ {
+ init_alloc_struct(&(hand->allocStruct), mallocFunc, mallocFuncContext, freeFunc,
+ freeFuncContext);
+ }
+}
+
+int elzma_compress_run(elzma_compress_handle hand, elzma_read_callback inputStream,
+ void *inputContext, elzma_write_callback outputStream,
+ void *outputContext, elzma_progress_callback progressCallback,
+ void *progressContext)
+{
+ struct elzmaInStream inStreamStruct;
+ struct elzmaOutStream outStreamStruct;
+ struct elzmaProgressStruct progressStruct;
+ SRes r;
+
+ CrcGenerateTable();
+
+ if (hand == NULL || inputStream == NULL)
+ return ELZMA_E_BAD_PARAMS;
+
+ /* initialize stream structrures */
+ inStreamStruct.ReadPtr = elzmaReadFunc;
+ inStreamStruct.inputStream = inputStream;
+ inStreamStruct.inputContext = inputContext;
+ inStreamStruct.crc32 = CRC_INIT_VAL;
+ inStreamStruct.calculateCRC = (hand->formatHandler.serialize_footer != NULL);
+
+ outStreamStruct.WritePtr = elzmaWriteFunc;
+ outStreamStruct.outputStream = outputStream;
+ outStreamStruct.outputContext = outputContext;
+
+ progressStruct.Progress = elzmaProgress;
+ progressStruct.uncompressedSize = hand->uncompressedSize;
+ progressStruct.progressCallback = progressCallback;
+ progressStruct.progressContext = progressContext;
+
+ /* create an encoding object */
+ hand->encHand = LzmaEnc_Create();
+
+ if (hand->encHand == NULL)
+ {
+ return ELZMA_E_COMPRESS_ERROR;
+ }
+
+ /* inintialize with compression parameters */
+ if (SZ_OK != LzmaEnc_SetProps(hand->encHand, &(hand->props)))
+ {
+ return ELZMA_E_BAD_PARAMS;
+ }
+
+ /* verify format is sane */
+ if (ELZMA_lzma != hand->format && ELZMA_lzip != hand->format)
+ {
+ return ELZMA_E_UNSUPPORTED_FORMAT;
+ }
+
+ /* now write the compression header header */
+ {
+ unsigned char *hdr =
+ hand->allocStruct.Alloc(&(hand->allocStruct), hand->formatHandler.header_size);
+
+ struct elzma_file_header h;
+ size_t wt;
+
+ hand->formatHandler.init_header(&h);
+ h.pb = (unsigned char)hand->props.pb;
+ h.lp = (unsigned char)hand->props.lp;
+ h.lc = (unsigned char)hand->props.lc;
+ h.dictSize = hand->props.dictSize;
+ h.isStreamed = (unsigned char)(hand->uncompressedSize == 0);
+ h.uncompressedSize = hand->uncompressedSize;
+
+ hand->formatHandler.serialize_header(hdr, &h);
+
+ wt = outputStream(outputContext, (void *)hdr, hand->formatHandler.header_size);
+
+ hand->allocStruct.Free(&(hand->allocStruct), hdr);
+
+ if (wt != hand->formatHandler.header_size)
+ {
+ return ELZMA_E_OUTPUT_ERROR;
+ }
+ }
+
+ /* begin LZMA encoding */
+ /* XXX: expose encoding progress */
+ r = LzmaEnc_Encode(hand->encHand, (ISeqOutStream *)&outStreamStruct,
+ (ISeqInStream *)&inStreamStruct, (ICompressProgress *)&progressStruct);
+
+ if (r != SZ_OK)
+ return ELZMA_E_COMPRESS_ERROR;
+
+ /* support a footer! (lzip) */
+ if (hand->formatHandler.serialize_footer != NULL && hand->formatHandler.footer_size > 0)
+ {
+ size_t wt;
+ unsigned char *ftrBuf =
+ hand->allocStruct.Alloc(&(hand->allocStruct), hand->formatHandler.footer_size);
+ struct elzma_file_footer ftr;
+ ftr.crc32 = inStreamStruct.crc32 ^ 0xFFFFFFFF;
+ ftr.uncompressedSize = hand->uncompressedSize;
+
+ hand->formatHandler.serialize_footer(&ftr, ftrBuf);
+
+ wt = outputStream(outputContext, (void *)ftrBuf, hand->formatHandler.footer_size);
+
+ hand->allocStruct.Free(&(hand->allocStruct), ftrBuf);
+
+ if (wt != hand->formatHandler.footer_size)
+ {
+ return ELZMA_E_OUTPUT_ERROR;
+ }
+ }
+
+ return ELZMA_E_OK;
+}
+
+unsigned int elzma_get_dict_size(unsigned long long size)
+{
+ int i = 13; /* 16k dict is minimum */
+
+ /* now we'll find the closes power of two with a max at 16< *
+ * if the size is greater than 8m, we'll divide by two, all of this
+ * is based on a quick set of emperical tests on hopefully
+ * representative sample data */
+ if (size > (1 << 23))
+ size >>= 1;
+
+ while (size >> i)
+ i++;
+
+ if (i > 23)
+ return 1 << 23;
+
+ /* now 1 << i is greater than size, let's return either 1<<i or 1<<(i-1),
+ * whichever is closer to size */
+ return 1 << ((((1 << i) - size) > (size - (1 << (i - 1)))) ? i - 1 : i);
+}
diff --git a/depends/lzma/wrapper/decompress.c b/depends/lzma/wrapper/decompress.c
new file mode 100644
index 00000000..65ff9119
--- /dev/null
+++ b/depends/lzma/wrapper/decompress.c
@@ -0,0 +1,263 @@
+/*
+ * Written in 2009 by Lloyd Hilaiel
+ *
+ * License
+ *
+ * All the cruft you find here is public domain. You don't have to credit
+ * anyone to use this code, but my personal request is that you mention
+ * Igor Pavlov for his hard, high quality work.
+ */
+
+#include "include/decompress.h"
+#include "pavlov/LzmaDec.h"
+#include "pavlov/7zCrc.h"
+#include "common_internal.h"
+#include "lzma_header.h"
+#include "lzip_header.h"
+
+#include <string.h>
+#include <assert.h>
+
+#define ELZMA_DECOMPRESS_INPUT_BUFSIZE (1024 * 64)
+#define ELZMA_DECOMPRESS_OUTPUT_BUFSIZE (1024 * 256)
+
+/** an opaque handle to an lzma decompressor */
+struct _elzma_decompress_handle
+{
+ char inbuf[ELZMA_DECOMPRESS_INPUT_BUFSIZE];
+ char outbuf[ELZMA_DECOMPRESS_OUTPUT_BUFSIZE];
+ struct elzma_alloc_struct allocStruct;
+};
+
+elzma_decompress_handle elzma_decompress_alloc()
+{
+ elzma_decompress_handle hand = malloc(sizeof(struct _elzma_decompress_handle));
+ memset((void *)hand, 0, sizeof(struct _elzma_decompress_handle));
+ init_alloc_struct(&(hand->allocStruct), NULL, NULL, NULL, NULL);
+ return hand;
+}
+
+void elzma_decompress_set_allocation_callbacks(elzma_decompress_handle hand,
+ elzma_malloc mallocFunc, void *mallocFuncContext,
+ elzma_free freeFunc, void *freeFuncContext)
+{
+ if (hand)
+ {
+ init_alloc_struct(&(hand->allocStruct), mallocFunc, mallocFuncContext, freeFunc,
+ freeFuncContext);
+ }
+}
+
+void elzma_decompress_free(elzma_decompress_handle *hand)
+{
+ if (*hand)
+ free(*hand);
+ *hand = NULL;
+}
+
+int elzma_decompress_run(elzma_decompress_handle hand, elzma_read_callback inputStream,
+ void *inputContext, elzma_write_callback outputStream,
+ void *outputContext, elzma_file_format format)
+{
+ unsigned long long int totalRead = 0; /* total amount read from stream */
+ unsigned int crc32 = CRC_INIT_VAL; /* running crc32 (lzip case) */
+ CLzmaDec dec;
+ unsigned int errorCode = ELZMA_E_OK;
+ struct elzma_format_handler formatHandler;
+ struct elzma_file_header h;
+ struct elzma_file_footer f;
+
+ /* switch between supported formats */
+ if (format == ELZMA_lzma)
+ {
+ initializeLZMAFormatHandler(&formatHandler);
+ }
+ else if (format == ELZMA_lzip)
+ {
+ CrcGenerateTable();
+ initializeLZIPFormatHandler(&formatHandler);
+ }
+ else
+ {
+ return ELZMA_E_BAD_PARAMS;
+ }
+
+ /* initialize footer */
+ f.crc32 = 0;
+ f.uncompressedSize = 0;
+
+ /* initialize decoder memory */
+ memset((void *)&dec, 0, sizeof(dec));
+ LzmaDec_Init(&dec);
+
+ /* decode the header. */
+ {
+ unsigned char *hdr =
+ hand->allocStruct.Alloc(&(hand->allocStruct), formatHandler.header_size);
+
+ size_t sz = formatHandler.header_size;
+
+ formatHandler.init_header(&h);
+
+ if (inputStream(inputContext, hdr, &sz) != 0 || sz != formatHandler.header_size)
+ {
+ hand->allocStruct.Free(&(hand->allocStruct), hdr);
+ return ELZMA_E_INPUT_ERROR;
+ }
+
+ if (0 != formatHandler.parse_header(hdr, &h))
+ {
+ hand->allocStruct.Free(&(hand->allocStruct), hdr);
+ return ELZMA_E_CORRUPT_HEADER;
+ }
+
+ /* the LzmaDec_Allocate call requires 5 bytes which have
+ * compression properties encoded in them. In the case of
+ * lzip, the header format does not already contain what
+ * LzmaDec_Allocate expects, so we must craft it, silly */
+ {
+ unsigned char propsBuf[13];
+ const unsigned char *propsPtr = hdr;
+
+ if (format == ELZMA_lzip)
+ {
+ struct elzma_format_handler lzmaHand;
+ initializeLZMAFormatHandler(&lzmaHand);
+ lzmaHand.serialize_header(propsBuf, &h);
+ propsPtr = propsBuf;
+ }
+
+ /* now we're ready to allocate the decoder */
+ LzmaDec_Allocate(&dec, propsPtr, 5);
+ }
+
+ hand->allocStruct.Free(&(hand->allocStruct), hdr);
+ }
+
+ /* perform the decoding */
+ for (;;)
+ {
+ size_t dstLen = ELZMA_DECOMPRESS_OUTPUT_BUFSIZE;
+ size_t srcLen = ELZMA_DECOMPRESS_INPUT_BUFSIZE;
+ size_t amt = 0;
+ size_t bufOff = 0;
+ ELzmaStatus stat;
+
+ if (0 != inputStream(inputContext, hand->inbuf, &srcLen))
+ {
+ errorCode = ELZMA_E_INPUT_ERROR;
+ goto decompressEnd;
+ }
+
+ /* handle the case where the input prematurely finishes */
+ if (srcLen == 0)
+ {
+ errorCode = ELZMA_E_INSUFFICIENT_INPUT;
+ goto decompressEnd;
+ }
+
+ amt = srcLen;
+
+ /* handle the case where a single read buffer of compressed bytes
+ * will translate into multiple buffers of uncompressed bytes,
+ * with this inner loop */
+ stat = LZMA_STATUS_NOT_SPECIFIED;
+
+ while (bufOff < srcLen)
+ {
+ SRes r = LzmaDec_DecodeToBuf(&dec, (uint8_t *)hand->outbuf, &dstLen,
+ ((uint8_t *)hand->inbuf + bufOff), &amt,
+ LZMA_FINISH_ANY, &stat);
+
+ /* XXX deal with result code more granularly*/
+ if (r != SZ_OK)
+ {
+ errorCode = ELZMA_E_DECOMPRESS_ERROR;
+ goto decompressEnd;
+ }
+
+ /* write what we've read */
+ {
+ size_t wt;
+
+ /* if decoding lzip, update our crc32 value */
+ if (format == ELZMA_lzip && dstLen > 0)
+ {
+ crc32 = CrcUpdate(crc32, hand->outbuf, dstLen);
+ }
+ totalRead += dstLen;
+
+ wt = outputStream(outputContext, hand->outbuf, dstLen);
+ if (wt != dstLen)
+ {
+ errorCode = ELZMA_E_OUTPUT_ERROR;
+ goto decompressEnd;
+ }
+ }
+
+ /* do we have more data on the input buffer? */
+ bufOff += amt;
+ assert(bufOff <= srcLen);
+ if (bufOff >= srcLen)
+ break;
+ amt = srcLen - bufOff;
+
+ /* with lzip, we will have the footer left on the buffer! */
+ if (stat == LZMA_STATUS_FINISHED_WITH_MARK)
+ {
+ break;
+ }
+ }
+
+ /* now check status */
+ if (stat == LZMA_STATUS_FINISHED_WITH_MARK)
+ {
+ /* read a footer if one is expected and
+ * present */
+ if (formatHandler.footer_size > 0 && amt >= formatHandler.footer_size &&
+ formatHandler.parse_footer != NULL)
+ {
+ formatHandler.parse_footer((unsigned char *)hand->inbuf + bufOff, &f);
+ }
+
+ break;
+ }
+ /* for LZMA utils, we don't always have a finished mark */
+ if (!h.isStreamed && totalRead >= h.uncompressedSize)
+ {
+ break;
+ }
+ }
+
+ /* finish the calculated crc32 */
+ crc32 ^= 0xFFFFFFFF;
+
+ /* if we have a footer, check that the calculated crc32 matches
+ * the encoded crc32, and that the sizes match */
+ if (formatHandler.footer_size)
+ {
+ if (f.crc32 != crc32)
+ {
+ errorCode = ELZMA_E_CRC32_MISMATCH;
+ }
+ else if (f.uncompressedSize != totalRead)
+ {
+ errorCode = ELZMA_E_SIZE_MISMATCH;
+ }
+ }
+ else if (!h.isStreamed)
+ {
+ /* if the format does not support a footer and has an uncompressed
+ * size in the header, let's compare that with how much we actually
+ * read */
+ if (h.uncompressedSize != totalRead)
+ {
+ errorCode = ELZMA_E_SIZE_MISMATCH;
+ }
+ }
+
+decompressEnd:
+ LzmaDec_Free(&dec);
+
+ return errorCode;
+}
diff --git a/depends/lzma/wrapper/lzip_header.c b/depends/lzma/wrapper/lzip_header.c
new file mode 100644
index 00000000..39872813
--- /dev/null
+++ b/depends/lzma/wrapper/lzip_header.c
@@ -0,0 +1,96 @@
+#include "lzip_header.h"
+
+#include <string.h>
+
+#define ELZMA_LZIP_HEADER_SIZE 6
+#define ELZMA_LZIP_FOOTER_SIZE 12
+
+static void initLzipHeader(struct elzma_file_header *hdr)
+{
+ memset((void *)hdr, 0, sizeof(struct elzma_file_header));
+}
+
+static int parseLzipHeader(const unsigned char *hdrBuf, struct elzma_file_header *hdr)
+{
+ if (0 != strncmp("LZIP", (char *)hdrBuf, 4))
+ return 1;
+ /* XXX: ignore version for now */
+ hdr->pb = 2;
+ hdr->lp = 0;
+ hdr->lc = 3;
+ /* unknown at this point */
+ hdr->isStreamed = 1;
+ hdr->uncompressedSize = 0;
+ hdr->dictSize = 1 << (hdrBuf[5] & 0x1F);
+ return 0;
+}
+
+static int serializeLzipHeader(unsigned char *hdrBuf, const struct elzma_file_header *hdr)
+{
+ hdrBuf[0] = 'L';
+ hdrBuf[1] = 'Z';
+ hdrBuf[2] = 'I';
+ hdrBuf[3] = 'P';
+ hdrBuf[4] = 0;
+ {
+ int r = 0;
+ while ((hdr->dictSize >> r) != 0)
+ r++;
+ hdrBuf[5] = (unsigned char)(r - 1) & 0x1F;
+ }
+ return 0;
+}
+
+static int serializeLzipFooter(struct elzma_file_footer *ftr, unsigned char *ftrBuf)
+{
+ unsigned int i = 0;
+
+ /* first crc32 */
+ for (i = 0; i < 4; i++)
+ {
+ *(ftrBuf++) = (unsigned char)(ftr->crc32 >> (i * 8));
+ }
+
+ /* next data size */
+ for (i = 0; i < 8; i++)
+ {
+ *(ftrBuf++) = (unsigned char)(ftr->uncompressedSize >> (i * 8));
+ }
+
+ /* write version 0 files, omit member length for now*/
+
+ return 0;
+}
+
+static int parseLzipFooter(const unsigned char *ftrBuf, struct elzma_file_footer *ftr)
+{
+ unsigned int i = 0;
+ ftr->crc32 = 0;
+ ftr->uncompressedSize = 0;
+
+ /* first crc32 */
+ for (i = 0; i < 4; i++)
+ {
+ ftr->crc32 += ((unsigned int)*(ftrBuf++) << (i * 8));
+ }
+
+ /* next data size */
+ for (i = 0; i < 8; i++)
+ {
+ ftr->uncompressedSize += (unsigned long long)*(ftrBuf++) << (i * 8);
+ }
+ /* read version 0 files, omit member length for now*/
+
+ return 0;
+}
+
+void initializeLZIPFormatHandler(struct elzma_format_handler *hand)
+{
+ hand->header_size = ELZMA_LZIP_HEADER_SIZE;
+ hand->init_header = initLzipHeader;
+ hand->parse_header = parseLzipHeader;
+ hand->serialize_header = serializeLzipHeader;
+ hand->footer_size = ELZMA_LZIP_FOOTER_SIZE;
+ hand->serialize_footer = serializeLzipFooter;
+ hand->parse_footer = parseLzipFooter;
+}
diff --git a/depends/lzma/wrapper/lzip_header.h b/depends/lzma/wrapper/lzip_header.h
new file mode 100644
index 00000000..138afa60
--- /dev/null
+++ b/depends/lzma/wrapper/lzip_header.h
@@ -0,0 +1,11 @@
+#ifndef __EASYLZMA_LZIP_HEADER__
+#define __EASYLZMA_LZIP_HEADER__
+
+#include "common_internal.h"
+
+/* lzip file format documented here:
+ * http://download.savannah.gnu.org/releases-noredirect/lzip/manual/ */
+
+void initializeLZIPFormatHandler(struct elzma_format_handler *hand);
+
+#endif
diff --git a/depends/lzma/wrapper/lzma_header.c b/depends/lzma/wrapper/lzma_header.c
new file mode 100644
index 00000000..ab32549f
--- /dev/null
+++ b/depends/lzma/wrapper/lzma_header.c
@@ -0,0 +1,134 @@
+/*
+ * Written in 2009 by Lloyd Hilaiel
+ *
+ * License
+ *
+ * All the cruft you find here is public domain. You don't have to credit
+ * anyone to use this code, but my personal request is that you mention
+ * Igor Pavlov for his hard, high quality work.
+ */
+
+/* XXX: clean this up, it's mostly lifted from pavel */
+
+#include "lzma_header.h"
+
+#include <string.h>
+#include <assert.h>
+
+#define ELZMA_LZMA_HEADER_SIZE 13
+#define ELZMA_LZMA_PROPSBUF_SIZE 5
+
+/****************
+ Header parsing
+ ****************/
+
+#ifndef UINT64_MAX
+#define UINT64_MAX ((unsigned long long)-1)
+#endif
+
+/* Parse the properties byte */
+static char lzmadec_header_properties(unsigned char *pb, unsigned char *lp, unsigned char *lc,
+ const unsigned char c)
+{
+ /* pb, lp and lc are encoded into a single byte. */
+ if (c > (9 * 5 * 5))
+ return -1;
+ *pb = c / (9 * 5); /* 0 <= pb <= 4 */
+ *lp = (c % (9 * 5)) / 9; /* 0 <= lp <= 4 */
+ *lc = c % 9; /* 0 <= lc <= 8 */
+
+ assert(*pb < 5 && *lp < 5 && *lc < 9);
+ return 0;
+}
+
+/* Parse the dictionary size (4 bytes, little endian) */
+static char lzmadec_header_dictionary(unsigned int *size, const unsigned char *buffer)
+{
+ unsigned int i;
+ *size = 0;
+ for (i = 0; i < 4; i++)
+ *size += (unsigned int)(*buffer++) << (i * 8);
+ /* The dictionary size is limited to 256 MiB (checked from
+ * LZMA SDK 4.30) */
+ if (*size > (1 << 28))
+ return -1;
+ return 0;
+}
+
+/* Parse the uncompressed size field (8 bytes, little endian) */
+static void lzmadec_header_uncompressed(unsigned long long *size, unsigned char *is_streamed,
+ const unsigned char *buffer)
+{
+ unsigned int i;
+
+ /* Streamed files have all 64 bits set in the size field.
+ * We don't know the uncompressed size beforehand. */
+ *is_streamed = 1; /* Assume streamed. */
+ *size = 0;
+ for (i = 0; i < 8; i++)
+ {
+ *size += (unsigned long long)buffer[i] << (i * 8);
+ if (buffer[i] != 255)
+ *is_streamed = 0;
+ }
+ assert((*is_streamed == 1 && *size == UINT64_MAX) ||
+ (*is_streamed == 0 && *size < UINT64_MAX));
+}
+
+static void initLzmaHeader(struct elzma_file_header *hdr)
+{
+ memset((void *)hdr, 0, sizeof(struct elzma_file_header));
+}
+
+static int parseLzmaHeader(const unsigned char *hdrBuf, struct elzma_file_header *hdr)
+{
+ if (lzmadec_header_properties(&(hdr->pb), &(hdr->lp), &(hdr->lc), *hdrBuf) ||
+ lzmadec_header_dictionary(&(hdr->dictSize), hdrBuf + 1))
+ {
+ return 1;
+ }
+ lzmadec_header_uncompressed(&(hdr->uncompressedSize), &(hdr->isStreamed), hdrBuf + 5);
+
+ return 0;
+}
+
+static int serializeLzmaHeader(unsigned char *hdrBuf, const struct elzma_file_header *hdr)
+{
+ unsigned int i;
+
+ memset((void *)hdrBuf, 0, ELZMA_LZMA_HEADER_SIZE);
+
+ /* encode lc, pb, and lp */
+ *hdrBuf++ = hdr->lc + (hdr->pb * 45) + (hdr->lp * 45 * 9);
+
+ /* encode dictionary size */
+ for (i = 0; i < 4; i++)
+ {
+ *(hdrBuf++) = (unsigned char)(hdr->dictSize >> (i * 8));
+ }
+
+ /* encode uncompressed size */
+ for (i = 0; i < 8; i++)
+ {
+ if (hdr->isStreamed)
+ {
+ *(hdrBuf++) = 0xff;
+ }
+ else
+ {
+ *(hdrBuf++) = (unsigned char)(hdr->uncompressedSize >> (i * 8));
+ }
+ }
+
+ return 0;
+}
+
+void initializeLZMAFormatHandler(struct elzma_format_handler *hand)
+{
+ hand->header_size = ELZMA_LZMA_HEADER_SIZE;
+ hand->init_header = initLzmaHeader;
+ hand->parse_header = parseLzmaHeader;
+ hand->serialize_header = serializeLzmaHeader;
+ hand->footer_size = 0;
+ hand->serialize_footer = NULL;
+}
diff --git a/depends/lzma/wrapper/lzma_header.h b/depends/lzma/wrapper/lzma_header.h
new file mode 100644
index 00000000..6a5d7a9c
--- /dev/null
+++ b/depends/lzma/wrapper/lzma_header.h
@@ -0,0 +1,10 @@
+#ifndef __EASYLZMA_LZMA_HEADER__
+#define __EASYLZMA_LZMA_HEADER__
+
+#include "common_internal.h"
+
+/* LZMA-Alone header format gleaned from reading Igor's code */
+
+void initializeLZMAFormatHandler(struct elzma_format_handler *hand);
+
+#endif
diff --git a/depends/lzma/wrapper/simple.c b/depends/lzma/wrapper/simple.c
new file mode 100644
index 00000000..98d3c285
--- /dev/null
+++ b/depends/lzma/wrapper/simple.c
@@ -0,0 +1,139 @@
+/*
+ * Written in 2009 by Lloyd Hilaiel
+ *
+ * License
+ *
+ * All the cruft you find here is public domain. You don't have to credit
+ * anyone to use this code, but my personal request is that you mention
+ * Igor Pavlov for his hard, high quality work.
+ *
+ * simple.c - a wrapper around easylzma to compress/decompress to memory
+ */
+
+#include "simple.h"
+
+#include <string.h>
+#include <assert.h>
+
+struct dataStream
+{
+ const unsigned char *inData;
+ size_t inLen;
+
+ unsigned char *outData;
+ size_t outLen;
+};
+
+static int inputCallback(void *ctx, void *buf, size_t *size)
+{
+ size_t rd = 0;
+ struct dataStream *ds = (struct dataStream *)ctx;
+ assert(ds != NULL);
+
+ rd = (ds->inLen < *size) ? ds->inLen : *size;
+
+ if (rd > 0)
+ {
+ memcpy(buf, (void *)ds->inData, rd);
+ ds->inData += rd;
+ ds->inLen -= rd;
+ }
+
+ *size = rd;
+
+ return 0;
+}
+
+static size_t outputCallback(void *ctx, const void *buf, size_t size)
+{
+ struct dataStream *ds = (struct dataStream *)ctx;
+ assert(ds != NULL);
+
+ if (size > 0)
+ {
+ ds->outData = realloc(ds->outData, ds->outLen + size);
+ memcpy((void *)(ds->outData + ds->outLen), buf, size);
+ ds->outLen += size;
+ }
+
+ return size;
+}
+
+int simpleCompress(elzma_file_format format, const unsigned char *inData, size_t inLen,
+ unsigned char **outData, size_t *outLen)
+{
+ int rc;
+ elzma_compress_handle hand;
+
+ /* allocate compression handle */
+ hand = elzma_compress_alloc();
+ assert(hand != NULL);
+
+ rc = elzma_compress_config(hand, ELZMA_LC_DEFAULT, ELZMA_LP_DEFAULT, ELZMA_PB_DEFAULT, 5,
+ (1 << 20) /* 1mb */, format, inLen);
+
+ if (rc != ELZMA_E_OK)
+ {
+ elzma_compress_free(&hand);
+ return rc;
+ }
+
+ /* now run the compression */
+ {
+ struct dataStream ds;
+ ds.inData = inData;
+ ds.inLen = inLen;
+ ds.outData = NULL;
+ ds.outLen = 0;
+
+ rc = elzma_compress_run(hand, inputCallback, (void *)&ds, outputCallback, (void *)&ds,
+ NULL, NULL);
+
+ if (rc != ELZMA_E_OK)
+ {
+ if (ds.outData != NULL)
+ free(ds.outData);
+ elzma_compress_free(&hand);
+ return rc;
+ }
+
+ *outData = ds.outData;
+ *outLen = ds.outLen;
+ }
+
+ return rc;
+}
+
+int simpleDecompress(elzma_file_format format, const unsigned char *inData, size_t inLen,
+ unsigned char **outData, size_t *outLen)
+{
+ int rc;
+ elzma_decompress_handle hand;
+
+ hand = elzma_decompress_alloc();
+
+ /* now run the compression */
+ {
+ struct dataStream ds;
+ ds.inData = inData;
+ ds.inLen = inLen;
+ ds.outData = NULL;
+ ds.outLen = 0;
+
+ rc = elzma_decompress_run(hand, inputCallback, (void *)&ds, outputCallback, (void *)&ds,
+ format);
+
+ if (rc != ELZMA_E_OK)
+ {
+ if (ds.outData != NULL)
+ free(ds.outData);
+ elzma_decompress_free(&hand);
+ return rc;
+ }
+
+ *outData = ds.outData;
+ *outLen = ds.outLen;
+ }
+
+ return rc;
+}