This commit is contained in:
Joshua Granick
2015-06-25 14:13:02 -07:00
parent 15fac4d6bd
commit f80adfae95
6 changed files with 187 additions and 34 deletions

View File

@@ -0,0 +1,94 @@
#include <utils/LZMA.h>
#include "LzmaEnc.h"
#include "LzmaDec.h"
namespace lime {
inline void WRITE_LE8 (unsigned char *ptr, char value) { *ptr = value; }
inline void WRITE_LE16 (unsigned char *ptr, short value) { WRITE_LE8 ((ptr) + 0, ((value) >> 0)); WRITE_LE8 ((ptr) + 1, ((value) >> 8)); }
inline void WRITE_LE32 (unsigned char *ptr, int value) { WRITE_LE16 ((ptr) + 0, ((value) >> 0)); WRITE_LE16 ((ptr) + 2, ((value) >> 16)); }
inline void WRITE_LE64 (unsigned char *ptr, Int64 value) { WRITE_LE32 ((ptr) + 0, ((value) >> 0)); WRITE_LE32 ((ptr) + 4, ((value) >> 32)); }
inline unsigned char READ_LE8 (unsigned char *ptr) { return *ptr; }
inline unsigned short READ_LE16 (unsigned char *ptr) { return ((unsigned short)READ_LE8 (ptr + 0) << 0) | ((unsigned short)READ_LE8 (ptr + 1) << 8); }
inline unsigned int READ_LE32 (unsigned char *ptr) { return ((unsigned int)READ_LE16 (ptr + 0) << 0) | ((unsigned int)READ_LE16 (ptr + 2) << 16); }
inline UInt64 READ_LE64 (unsigned char *ptr) { return ((UInt64)READ_LE32 (ptr + 0) << 0) | ((UInt64)READ_LE32 (ptr + 4) << 32); }
extern "C" {
SRes LZMA_progress (void *p, UInt64 inSize, UInt64 outSize) { return SZ_OK; }
void *LZMA_alloc (void *p, size_t size) { return malloc (size); }
void LZMA_free(void *p, void *address) {
if (address == NULL) return;
free (address);
}
}
void LZMA::Decode (Bytes* data, Bytes* result) {
SizeT inputBufferSize = data->Length ();
Byte* inputBufferData = data->Data ();
Int64 uncompressedLength = -1;
ELzmaStatus status = LZMA_STATUS_NOT_SPECIFIED;
ISzAlloc alloc = { LZMA_alloc, LZMA_free };
CLzmaProps props = { 0 };
LzmaProps_Decode (&props, inputBufferData, LZMA_PROPS_SIZE);
uncompressedLength = READ_LE64 (inputBufferData + LZMA_PROPS_SIZE);
result->Resize ((int)uncompressedLength);
SizeT outputBufferSize = result->Length ();
Byte* outputBufferData = result->Data ();
Byte* _inputBufferData = inputBufferData + LZMA_PROPS_SIZE + sizeof (uncompressedLength);
SizeT _inputBufferSize = inputBufferSize - LZMA_PROPS_SIZE - sizeof (uncompressedLength);
LzmaDecode (outputBufferData, &outputBufferSize, _inputBufferData, &_inputBufferSize, inputBufferData, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &alloc);
}
void LZMA::Encode (Bytes* data, Bytes* result) {
SizeT inputBufferSize = data->Length ();
Byte* inputBufferData = data->Data ();
result->Resize (inputBufferSize + 1024);
SizeT outputBufferSize = result->Length ();
Byte* outputBufferData = result->Data ();
SizeT propsSize = 100;
Byte* propsData = (Byte *)malloc (propsSize);
Int64 uncompressedLength = inputBufferSize;
CLzmaEncProps props = { 0 };
LzmaEncProps_Init (&props);
props.dictSize = (1 << 20);
props.writeEndMark = 0;
props.numThreads = 1;
ICompressProgress progress = { LZMA_progress };
ISzAlloc allocSmall = { LZMA_alloc, LZMA_free };
ISzAlloc allocBig = { LZMA_alloc, LZMA_free };
LzmaEncode (outputBufferData + propsSize + 8, &outputBufferSize, inputBufferData, inputBufferSize, &props, propsData, &propsSize, props.writeEndMark, &progress, &allocSmall, &allocBig);
memcpy (outputBufferData, propsData, propsSize);
WRITE_LE64 (outputBufferData + propsSize, uncompressedLength);
free(propsData);
}
}