From 671140f906333bbc46d5db8766a7759c85506ffa Mon Sep 17 00:00:00 2001 From: Charles Wilson Date: Sun, 14 Mar 2010 17:45:18 +0000 Subject: [PATCH] Support xz and lzma decompression via liblzma * Makefile.am: Add -DLZMA_API_STATIC to AM_CPPFLAGS, -lzma to setup_LDADD, and -static-libtool-libs to setup_LDFLAGS. Update setup_SOURCES. * compress.cc: Update includes. (compress::decompress): Use compress_xz rather than compress_lzma; compress_xz supports both xz and lzma decompression. * compress_xz.h: New. * compress_xz.cc: New. * compress_lzma.h: Removed. * compress_lzma.cc: Removed. * lzma-sdk/LzmaDec.c: Removed. * lzma-sdk/LzmaDec.h: Removed. * lzma-sdk/Types.h: Removed. --- ChangeLog | 18 + Makefile.am | 15 +- compress.cc | 8 +- compress_lzma.cc | 402 ------------------ compress_lzma.h | 73 ---- compress_xz.cc | 623 +++++++++++++++++++++++++++ compress_xz.h | 87 ++++ lzma-sdk/LzmaDec.c | 1014 -------------------------------------------- lzma-sdk/LzmaDec.h | 241 ----------- lzma-sdk/Types.h | 140 ------ 10 files changed, 738 insertions(+), 1883 deletions(-) delete mode 100644 compress_lzma.cc delete mode 100644 compress_lzma.h create mode 100644 compress_xz.cc create mode 100644 compress_xz.h delete mode 100644 lzma-sdk/LzmaDec.c delete mode 100644 lzma-sdk/LzmaDec.h delete mode 100644 lzma-sdk/Types.h diff --git a/ChangeLog b/ChangeLog index 5ae64872..4953e867 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2010-03-14 Charles Wilson + + Support xz and lzma decompression via liblzma + * Makefile.am: Add -DLZMA_API_STATIC to AM_CPPFLAGS, + -lzma to setup_LDADD, and -static-libtool-libs to + setup_LDFLAGS. Update setup_SOURCES. + * compress.cc: Update includes. + (compress::decompress): Use compress_xz rather than + compress_lzma; compress_xz supports both xz and lzma + decompression. + * compress_xz.h: New. + * compress_xz.cc: New. + * compress_lzma.h: Removed. + * compress_lzma.cc: Removed. + * lzma-sdk/LzmaDec.c: Removed. + * lzma-sdk/LzmaDec.h: Removed. + * lzma-sdk/Types.h: Removed. + 2010-03-13 DJ Delorie * nio-ftp.c (read): Read RETR status code on EOF to avoid diff --git a/Makefile.am b/Makefile.am index 74c7fd48..6c5ea0b1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,7 +36,7 @@ AM_CFLAGS = $(AM_CXXFLAGS) -Wmissing-declarations -Winline \ AM_YFLAGS = -d AM_LFLAGS = -8 WINDRES = @WINDRES@ -AM_CPPFLAGS = -I$(srcdir)/libgetopt++/include -I$(top_builddir)/libgpg-error/src -I$(top_builddir)/libgcrypt/src -I$(srcdir)/libgcrypt/src +AM_CPPFLAGS = -DLZMA_API_STATIC -I$(srcdir)/libgetopt++/include -I$(top_builddir)/libgpg-error/src -I$(top_builddir)/libgcrypt/src -I$(srcdir)/libgcrypt/src noinst_PROGRAMS = setup @INILINT@ @@ -119,8 +119,8 @@ libinilex_a_CXXFLAGS = $(BASECXXFLAGS) setup_LDADD = \ libinilex.a \ -Linst/lib -lgetopt++ -lgcrypt -lgpg-error \ - -lshlwapi -lcomctl32 -lole32 -lwsock32 -lnetapi32 -luuid -lbz2 -lz -setup_LDFLAGS = -mwindows -Wl,-static + -lshlwapi -lcomctl32 -lole32 -lwsock32 -lnetapi32 -luuid -llzma -lbz2 -lz +setup_LDFLAGS = -mwindows -Wl,-static -static-libtool-libs setup_SOURCES = \ AntiVirus.cc \ AntiVirus.h \ @@ -138,8 +138,8 @@ setup_SOURCES = \ compress_bz.h \ compress_gz.cc \ compress_gz.h \ - compress_lzma.cc \ - compress_lzma.h \ + compress_xz.cc \ + compress_xz.h \ ConnectionSetting.cc \ ConnectionSetting.h \ ControlAdjuster.cc \ @@ -285,10 +285,7 @@ setup_SOURCES = \ csu_util/version_compare.cc \ csu_util/version_compare.h \ libmd5-rfc/md5.c \ - libmd5-rfc/md5.h \ - lzma-sdk/LzmaDec.c \ - lzma-sdk/LzmaDec.h \ - lzma-sdk/Types.h + libmd5-rfc/md5.h VER := $(shell sed -ne 's/^\$$Revi[s]ion: *\([^ ]*\) *$$.*/\1/p' \ $(srcdir)/ChangeLog) diff --git a/compress.cc b/compress.cc index 7de7bbe7..2be9f729 100644 --- a/compress.cc +++ b/compress.cc @@ -16,7 +16,7 @@ #include "compress.h" #include "compress_gz.h" #include "compress_bz.h" -#include "compress_lzma.h" +#include "compress_xz.h" /* In case you are wondering why the file magic is not in one place: * It could be. But there is little (any?) benefit. @@ -27,7 +27,7 @@ * the class could test itself. */ -#define longest_magic LZMA_PROPS_SIZE + 8 +#define longest_magic 14 /* lzma_alone */ io_stream * compress::decompress (io_stream * original) @@ -58,9 +58,9 @@ compress::decompress (io_stream * original) delete rv; return NULL; } - else if (compress_lzma::is_lzma (magic, LZMA_PROPS_SIZE + 8)) + else if (compress_xz::is_xz_or_lzma (magic, 14)) { - compress_lzma *rv = new compress_lzma (original); + compress_xz *rv = new compress_xz (original); if (!rv->error ()) return rv; /* else */ diff --git a/compress_lzma.cc b/compress_lzma.cc deleted file mode 100644 index d92e7e55..00000000 --- a/compress_lzma.cc +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (c) 2008, Charles Wilson - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * A copy of the GNU General Public License can be found at - * http://www.gnu.org/ - * - * Written by Charles Wilson - * - */ - -#include "compress_lzma.h" - -#include -using namespace std; -#include -#include -#include - -/* - * allocator for LzmaDec - */ -static void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); } -static void SzFree(void *p, void *address) { p = p; free(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - -/* - * Predicate: the stream is open for read. - */ -compress_lzma::compress_lzma (io_stream * parent) -: - original(NULL), - owns_original(true), - peeklen(0), - lasterr(0), - initializedOk(true), - unpackSize(0), - thereIsSize(false), - inbuf(NULL), - outbuf(NULL), - outp(NULL), - inPos(0), - inSize(0), - outPos(0), - inProcessed(0), - outProcessed(0) -{ - /* read only */ - if (!parent || parent->error()) - { - lasterr = EBADF; - return; - } - original = parent; - - inbuf = (unsigned char *) malloc (IN_BUF_SIZE); - if (!inbuf) - { - lasterr = ENOMEM; - return; - } - - outbuf = (unsigned char *) malloc (OUT_BUF_SIZE); - if (!outbuf) - { - lasterr = ENOMEM; - destroy(); - return; - } - - errno = 0; - check_header (); /* parse the header, and position fp */ - - outPos = 0; - inPos = 0; - inSize = 0; - outp = outbuf; - inProcessed = 0; - outProcessed = 0; - return; -} - -ssize_t -compress_lzma::read (void *buffer, size_t len) -{ - - if (!this->initializedOk) - return -1; - - /* there is no recovery from a busted stream */ - if (this->lasterr) - return -1; - - if (len == 0) - return 0; - - /* peekbuf is layered on top of existing buffering code */ - if (this->peeklen) - { - ssize_t tmplen = std::min (this->peeklen, len); - this->peeklen -= tmplen; - memcpy (buffer, this->peekbuf, tmplen); - memmove (this->peekbuf, this->peekbuf + tmplen, sizeof(this->peekbuf) - tmplen); - ssize_t tmpread = read (&((char *) buffer)[tmplen], len - tmplen); - if (tmpread >= 0) - return tmpread + tmplen; - else - return tmpread; - } - - if (this->outp < this->outbuf + this->outPos) - /* outp - outbuf < outPos, but avoid sign/unsigned warning */ - { - ssize_t tmplen = std::min ((size_t)(this->outbuf + this->outPos - this->outp), len); - memcpy (buffer, this->outp, tmplen); - this->outp += tmplen; - ssize_t tmpread = read (&((char *) buffer)[tmplen], len - tmplen); - if (tmpread >= 0) - return tmpread + tmplen; - else - return tmpread; - } - - size_t lenRemaining = len; - unsigned char * bufp = (unsigned char *)buffer; - /* if we made it here, any existing uncompressed data in outbuf - * has been consumed, so reset outp and outPos - */ - this->outp = this->outbuf; - this->outPos = 0; - do - { - if (this->inPos == this->inSize) - { - this->inSize = (size_t) this->original->read(this->inbuf, IN_BUF_SIZE); - this->inPos = 0; - } - - /* at this point, these two variables actually hold the number - * of bytes *available* to be processed or filled - */ - this->inProcessed = this->inSize - this->inPos; - this->outProcessed = OUT_BUF_SIZE - this->outPos; - - - ELzmaFinishMode finishMode = LZMA_FINISH_ANY; - if (this->thereIsSize && this->outProcessed > this->unpackSize) - { - this->outProcessed = unpackSize; - finishMode = LZMA_FINISH_END; - } - - ELzmaStatus status; - int res = LzmaDec_DecodeToBuf( - &(this->state), - this->outbuf + this->outPos, - &(this->outProcessed), - this->inbuf + this->inPos, - &(this->inProcessed), - finishMode, - &status); - this->inPos += (UInt32)this->inProcessed; - this->outPos += this->outProcessed; - this->unpackSize -= this->outProcessed; - - ssize_t tmplen = std::min (this->outProcessed, lenRemaining); - memcpy (bufp, outp, tmplen); - outp += tmplen; - bufp += tmplen; - lenRemaining -= tmplen; - - if (res != SZ_OK) - { - lasterr = res; - return -1; - } - - - if (this->thereIsSize && this->unpackSize == 0) - { - /* expected EOF */ - break; - } - if (this->inProcessed == 0 && this->outProcessed == 0) - { - if (this->thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK) - { - lasterr = EIO; - return -1; - } - break; - } - if (lenRemaining == 0) - { - /* fulfilled request */ - break; - } - } - while (true); - - return (len - lenRemaining); -} - -ssize_t -compress_lzma::write (const void *buffer, size_t len) -{ - throw new logic_error("compress_lzma::write is not implemented"); -} - -ssize_t -compress_lzma::peek (void *buffer, size_t len) -{ - /* can only peek 512 bytes */ - if (len > 512) - return ENOMEM; - - if (len > this->peeklen) - { - size_t want = len - this->peeklen; - ssize_t got = read (&(this->peekbuf[peeklen]), want); - if (got >= 0) - this->peeklen += got; - else - /* error */ - return got; - /* we may have read less than requested. */ - memcpy (buffer, this->peekbuf, this->peeklen); - return this->peeklen; - } - else - { - memcpy (buffer, this->peekbuf, len); - return len; - } - return 0; -} - -long -compress_lzma::tell () -{ - throw new logic_error("compress_lzma::tell is not implemented"); -} - -int -compress_lzma::seek (long where, io_stream_seek_t whence) -{ - throw new logic_error("compress_lzma::seek is not implemented"); -} - -int -compress_lzma::error () -{ - return lasterr; -} - -int -compress_lzma::set_mtime (time_t mtime) -{ - if (original) - return original->set_mtime (mtime); - return 1; -} - -time_t -compress_lzma::get_mtime () -{ - if (original) - return original->get_mtime (); - return 0; -} - -mode_t -compress_lzma::get_mode () -{ - if (original) - return original->get_mode (); - return 0; -} - -void -compress_lzma::release_original () -{ - owns_original = false; -} - -void -compress_lzma::destroy () -{ - if (this->initializedOk) - { - LzmaDec_Free(&(this->state), &g_Alloc); - } - if (this->inbuf) - { - free (this->inbuf); - this->inbuf = NULL; - } - if (this->outbuf) - { - free (this->outbuf); - this->outbuf = NULL; - } - - if (original && owns_original) - delete original; -} - -compress_lzma::~compress_lzma () -{ - destroy (); -} - -/* =========================================================================== - * Check the header of a lzma_stream opened for reading. - * IN assertion: - * the stream s has already been created sucessfully - * this method is called only once per stream - */ -void -compress_lzma::check_header () -{ - this->initializedOk = false; - this->thereIsSize = false; - this->unpackSize = 0; - - /* read properties */ - if (this->original->read(this->header, sizeof(this->header)) != sizeof(this->header)) - { - this->lasterr = (errno ? errno : EIO); - return; - } - - /* read uncompressed size */ - for (int i = 0; i < 8; i++) - { - unsigned char b = this->header[LZMA_PROPS_SIZE + i]; - if (b != 0xFF) - { - this->thereIsSize = true; - } - this->unpackSize += (UInt64)b << (i * 8); - } - - /* Decode LZMA properties and allocate memory */ - LzmaDec_Construct(&(this->state)); - int res = LzmaDec_Allocate(&(this->state), this->header, LZMA_PROPS_SIZE, &g_Alloc); - if (res != SZ_OK) - { - lasterr = res; - return; - } - - LzmaDec_Init(&(this->state)); - initializedOk = true; -} - -/* =========================================================================== - * duplicates a lot of code in check_header, but we don't want - * to read "too much" from the stream in the check_header case. - * Here, we don't care because we know compress will call this - * method with a peek'ed buffer. We also do not want to modify - * the member variables 'header' and 'state'. - */ -bool -compress_lzma::is_lzma (void * buffer, size_t len) -{ - unsigned char local_header[LZMA_PROPS_SIZE + 8]; - CLzmaDec local_state; - UInt64 local_unpackSize = 0; - bool local_thereIsSize = false; - - /* read header */ - if (len < LZMA_PROPS_SIZE + 8) - { - return false; - } - memcpy((void*)local_header, buffer, sizeof(local_header)); - - /* read uncompressed size */ - for (int i = 0; i < 8; i++) - { - unsigned char b = local_header[LZMA_PROPS_SIZE + i]; - if (b != 0xFF) - { - local_thereIsSize = true; - } - local_unpackSize += (UInt64)b << (i * 8); - } - - /* decode header */ - if (LzmaProps_Decode(&(local_state.prop), local_header, LZMA_PROPS_SIZE) != SZ_OK) - { - return false; - } - - return true; -} - diff --git a/compress_lzma.h b/compress_lzma.h deleted file mode 100644 index 0832371f..00000000 --- a/compress_lzma.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2008, Charles Wilson - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * A copy of the GNU General Public License can be found at - * http://www.gnu.org/ - * - * Written by Charles Wilson - * - */ - -#ifndef SETUP_COMPRESS_LZMA_H -#define SETUP_COMPRESS_LZMA_H - -/* this is the parent class for all compress IO operations. - */ - -#include "compress.h" -#include "lzma-sdk/LzmaDec.h" - -class compress_lzma:public compress -{ -public: - compress_lzma (io_stream *); /* decompress (read) only */ - virtual ssize_t read (void *buffer, size_t len); - virtual ssize_t write (const void *buffer, size_t len); /* not implemented */ - virtual ssize_t peek (void *buffer, size_t len); - virtual long tell (); /* not implemented */ - virtual int seek (long where, io_stream_seek_t whence); /* not implemented */ - virtual int error (); - virtual const char *next_file_name () { return NULL; }; - virtual int set_mtime (time_t); - virtual time_t get_mtime (); - virtual mode_t get_mode (); - virtual size_t get_size () {return 0;}; - virtual ~compress_lzma (); - static bool is_lzma(void *buffer, size_t len); - virtual void release_original(); /* give up ownership of original io_stream */ - -private: - compress_lzma () {}; - - io_stream *original; - bool owns_original; - char peekbuf[512]; - size_t peeklen; - int lasterr; - bool initializedOk; - void check_header (); - void destroy (); - - /* from lzma */ - static const size_t IN_BUF_SIZE = (1 << 16); - static const size_t OUT_BUF_SIZE = (1 << 16); - unsigned char header[LZMA_PROPS_SIZE + 8]; - UInt64 unpackSize; - bool thereIsSize; /* true means header specifies uncompressed size */ - CLzmaDec state; - unsigned char * inbuf; - unsigned char * outbuf; - unsigned char * outp; - size_t inPos; - size_t inSize; - size_t outPos; - SizeT inProcessed; - SizeT outProcessed; -}; - -#endif /* SETUP_COMPRESS_LZMA_H */ diff --git a/compress_xz.cc b/compress_xz.cc new file mode 100644 index 00000000..6c9980b2 --- /dev/null +++ b/compress_xz.cc @@ -0,0 +1,623 @@ +/* + * Copyright (c) 2008, Charles Wilson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + * Written by Charles Wilson + * + * Portions of bid_xz() and bid_lzma() adapted from the libarchive + * archive_read_support_compression_xz.c functions xz_bidder_bid() + * and lzma_bidder_bid(), which are under a BSD license (reproduced + * below). + */ + +#include "compress_xz.h" +#include "msg.h" + +#include +using namespace std; +#include +#include +#include + +static inline uint32_t +le32dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); +} + +static inline uint64_t +le64dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p)); +} + +/* + * Predicate: the stream is open for read. + */ +compress_xz::compress_xz (io_stream * parent) +: + original(NULL), + owns_original(true), + peeklen(0), + lasterr(0), + compression_type (COMPRESSION_UNKNOWN) +{ + unsigned char * out_block = NULL; + unsigned char * in_block = NULL; + + /* read only */ + if (!parent || parent->error()) + { + lasterr = EBADF; + return; + } + original = parent; + + state = (struct private_data *)calloc(sizeof(*state), 1); + out_block = (unsigned char *)malloc(out_block_size); + in_block = (unsigned char *)malloc(in_block_size); + if (state == NULL || out_block == NULL || in_block == NULL) + { + free(out_block); + free(in_block); + free(state); + lasterr = ENOMEM; + return; + } + + memset(&(state->stream), 0x00, sizeof(state->stream)); + state->out_block_size = out_block_size; + state->out_block = out_block; + state->in_block_size = in_block_size; + state->in_block = in_block; + state->out_p = out_block; + state->stream.avail_in = 0; + state->stream.next_out = state->out_block; + state->stream.avail_out = state->out_block_size; + + init_decoder (); +} + +ssize_t +compress_xz::read (void *buffer, size_t len) +{ + if ( compression_type != COMPRESSION_XZ + && compression_type != COMPRESSION_LZMA) + { + return -1; + } + + /* there is no recovery from a busted stream */ + if (this->lasterr) + { + return -1; + } + if (len == 0) + { + return 0; + } + + /* peekbuf is layered on top of existing buffering code */ + if (this->peeklen) + { + ssize_t tmplen = std::min (this->peeklen, len); + this->peeklen -= tmplen; + memcpy (buffer, this->peekbuf, tmplen); + memmove (this->peekbuf, this->peekbuf + tmplen, sizeof(this->peekbuf) - tmplen); + ssize_t tmpread = read (&((char *) buffer)[tmplen], len - tmplen); + if (tmpread >= 0) + return tmpread + tmplen; + else + return tmpread; + } + + if (state->out_p < state->out_block + state->out_pos) + /* out_p - out_block < out_pos, but avoid sign/unsigned warning */ + { + ssize_t tmplen = std::min ((size_t)(state->out_block + state->out_pos - state->out_p), len); + memcpy (buffer, state->out_p, tmplen); + state->out_p += tmplen; + ssize_t tmpread = read (&((char *) buffer)[tmplen], len - tmplen); + if (tmpread >= 0) + return tmpread + tmplen; + else + return tmpread; + } + + size_t lenRemaining = len; + unsigned char * bufp = (unsigned char *)buffer; + size_t avail_in = 0; + size_t avail_out = 0; + size_t decompressed = 0; + size_t consumed = 0; + /* if we made it here, any existing uncompressed data in out_block + * has been consumed, so reset out_p and out_pos + */ + state->out_p = state->out_block; + state->out_pos = 0; + do + { + if (state->in_pos == state->in_size) + { + /* no compressed data ready; read some more */ + state->in_size = (size_t) this->original->read(state->in_block, state->in_block_size); + state->in_pos = 0; + } + + avail_in = state->in_size - state->in_pos; /* will be 0 if EOF */ + avail_out = state->out_block_size - state->out_pos; + + state->stream.next_out = state->out_block + state->out_pos; + state->stream.avail_out = avail_out; + state->stream.next_in = state->in_block + state->in_pos; + state->stream.avail_in = avail_in; + + lzma_ret res = lzma_code (&(state->stream), + (state->stream.avail_in == 0) ? LZMA_FINISH : LZMA_RUN); + + consumed = avail_in - state->stream.avail_in; + decompressed = avail_out - state->stream.avail_out; + + state->in_pos += consumed; + state->out_pos += decompressed; + + ssize_t tmplen = std::min (decompressed, lenRemaining); + memcpy (bufp, state->out_p, tmplen); + state->out_p += tmplen; + bufp += tmplen; + lenRemaining -= tmplen; + state->total_out += decompressed; + state->total_in += consumed; + + switch (res) + { + case LZMA_STREAM_END: /* Found end of stream. */ + state->eof = 1; + /* FALL THROUGH */ + case LZMA_OK: /* Decompressor made some progress. */ + break; + case LZMA_MEM_ERROR: + msg ("Lzma library error: Cannot allocate memory\n"); + this->lasterr = ENOMEM; + return -1; + case LZMA_MEMLIMIT_ERROR: + msg ("Lzma library error: Out of memory\n"); + this->lasterr = ENOMEM; + return -1; + case LZMA_FORMAT_ERROR: + msg ("Lzma library error: format not recognized\n"); + this->lasterr = EINVAL; + return -1; + case LZMA_OPTIONS_ERROR: + msg ("Lzma library error: Invalid options\n"); + this->lasterr = EINVAL; + return -1; + case LZMA_DATA_ERROR: + msg ("Lzma library error: Corrupted input data\n"); + this->lasterr = EINVAL; + return -1; + case LZMA_BUF_ERROR: + msg ("Lzma library error: No progress is possible\n"); + this->lasterr = EINVAL; + return -1; + case LZMA_PROG_ERROR: + msg ("Lzma library error: Internal error\n"); + this->lasterr = EINVAL; + return -1; + default: + msg ("Lzma decompression failed: Unknown error %d\n", res); + this->lasterr = EINVAL; + return -1; + } + } + while (lenRemaining != 0 && !state->eof); + + return (len - lenRemaining); +} + +ssize_t +compress_xz::write (const void *buffer, size_t len) +{ + throw new logic_error("compress_xz::write is not implemented"); +} + +ssize_t +compress_xz::peek (void *buffer, size_t len) +{ + /* can only peek 512 bytes */ + if (len > 512) + return ENOMEM; + + if (len > this->peeklen) + { + size_t want = len - this->peeklen; + ssize_t got = read (&(this->peekbuf[peeklen]), want); + if (got >= 0) + this->peeklen += got; + else + /* error */ + return got; + /* we may have read less than requested. */ + memcpy (buffer, this->peekbuf, this->peeklen); + return this->peeklen; + } + else + { + memcpy (buffer, this->peekbuf, len); + return len; + } + return 0; +} + +long +compress_xz::tell () +{ + throw new logic_error("compress_xz::tell is not implemented"); +} + +int +compress_xz::seek (long where, io_stream_seek_t whence) +{ + throw new logic_error("compress_xz::seek is not implemented"); +} + +int +compress_xz::error () +{ + return lasterr; +} + +int +compress_xz::set_mtime (time_t mtime) +{ + if (original) + return original->set_mtime (mtime); + return 1; +} + +time_t +compress_xz::get_mtime () +{ + if (original) + return original->get_mtime (); + return 0; +} + +mode_t +compress_xz::get_mode () +{ + if (original) + return original->get_mode (); + return 0; +} + +void +compress_xz::release_original () +{ + owns_original = false; +} + +void +compress_xz::destroy () +{ + if (state) + { + if ( compression_type == COMPRESSION_XZ + || compression_type == COMPRESSION_LZMA) + { + lzma_end(&(state->stream)); + } + + if (state->out_block) + { + free (state->out_block); + state->out_block = NULL; + } + + if (state->in_block) + { + free (state->in_block); + state->in_block = NULL; + } + + free(state); + state = NULL; + + compression_type = COMPRESSION_UNKNOWN; + } + + if (original && owns_original) + delete original; +} + +compress_xz::~compress_xz () +{ + destroy (); +} + +/* =========================================================================== + * Check the header of a lzma_stream opened for reading, and initialize + * the appropriate decoder (xz or lzma). + * IN assertion: + * the stream has already been created sucessfully + * this method is called only once per stream + * OUT assertion - success: + * compression_type is set to COMPRESSION_XZ or COMPRESSION_LZMA + * state->stream is initialized with the appropriate decoder + * lzma: the first 14 bytes of the stream are read (+ whatever + * the decoder itself consumes on initialization) + * xz: the first 6 bytes of the stram are read (+ whatever the + * decoder itself consumes on initialization) + * last_error is zero + * OUT assertion - error: + * last_error is non-zero + */ +void +compress_xz::init_decoder (void) +{ + unsigned char buf[14]; + int ret; + this->compression_type = COMPRESSION_UNKNOWN; + + /* read properties */ + if (this->original->peek (buf, 6) != 6) + { + this->lasterr = (errno ? errno : EIO); + return; + } + + if (bid_xz ((void *)buf, 6) > 0) + { + this->compression_type = COMPRESSION_XZ; + } + else + { + if (this->original->peek (buf + 6, 8) != 8) + { + this->lasterr = (errno ? errno : EIO); + return; + } + if (bid_lzma ((void *)buf, 14) > 0) + { + this->compression_type = COMPRESSION_LZMA; + } + } + + switch (compression_type) + { + case COMPRESSION_XZ: + ret = lzma_stream_decoder (&(state->stream), + (1U << 30),/* memlimit */ + LZMA_CONCATENATED); + break; + case COMPRESSION_LZMA: + ret = lzma_alone_decoder (&(state->stream), + (1U << 30));/* memlimit */ + break; + default: + this->lasterr = EINVAL; + return; + } + + switch (ret) + { + case LZMA_OK: + break; + case LZMA_MEM_ERROR: + this->lasterr = ENOMEM; + break; + case LZMA_OPTIONS_ERROR: + this->lasterr = EINVAL; + break; + default: + this->lasterr = EINVAL; + break; + } +} + +bool +compress_xz::is_xz_or_lzma (void * buffer, size_t len) +{ + int bits_checked_xz; + int bits_checked_lzma; + + bits_checked_xz = bid_xz (buffer, len); + if (bits_checked_xz) + return true; + + bits_checked_lzma = bid_lzma (buffer, len); + if (bits_checked_lzma) + return true; + + return false; +} + +/*- + * Portions of bid_xz() and bid_lzma() have been adapted from the + * libarchive archive_read_support_compression_xz.c functions + * xz_bidder_bid() and lzma_bidder_bid(), which were released under + * the 2-clause (simplified) BSD license, reproduced below. + * + * (modifications for setup.exe) Copyright (c) 2010 Charles Wilson + * Copyright (c) 2009 Michihiro NAKAJIMA + * Copyright (c) 2003-2008 Tim Kientzle and Miklos Vajna + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +int +compress_xz::bid_xz (void * buffer, size_t len) +{ + const unsigned char *buf; + int bits_checked; + + buf = (const unsigned char *)buffer; + if (len < 6) + { + /* not enough peek'ed data in buf */ + return 0; + } + + /* + * Verify Header Magic Bytes : FD 37 7A 58 5A 00 + */ + bits_checked = 0; + if (buf[0] != 0xFD) + return 0; + bits_checked += 8; + if (buf[1] != 0x37) + return 0; + bits_checked += 8; + if (buf[2] != 0x7A) + return 0; + bits_checked += 8; + if (buf[3] != 0x58) + return 0; + bits_checked += 8; + if (buf[4] != 0x5A) + return 0; + bits_checked += 8; + if (buf[5] != 0x00) + return 0; + bits_checked += 8; + + msg ("compress_xz::bid_xz: success: %d\n", bits_checked); + return (bits_checked); +} + +int +compress_xz::bid_lzma (void * buffer, size_t len) +{ + const unsigned char *buf; + uint32_t dicsize; + uint64_t uncompressed_size; + int bits_checked; + + if (len < 14) + { + /* not enough peek'ed data in buffer */ + return 0; + } + buf = (unsigned char *)buffer; + + /* First byte of raw LZMA stream is commonly 0x5d. + * The first byte is a special number, which consists of + * three parameters of LZMA compression, a number of literal + * context bits(which is from 0 to 8, default is 3), a number + * of literal pos bits(which is from 0 to 4, default is 0), + * a number of pos bits(which is from 0 to 4, default is 2). + * The first byte is made by + * (pos bits * 5 + literal pos bit) * 9 + * literal contest bit, + * and so the default value in this field is + * (2 * 5 + 0) * 9 + 3 = 0x5d. + * lzma of LZMA SDK has options to change those parameters. + * It means a range of this field is from 0 to 224. And lzma of + * XZ Utils with option -e records 0x5e in this field. */ + /* NOTE: If this checking of the first byte increases false + * recognition, we should allow only 0x5d and 0x5e for the first + * byte of LZMA stream. */ + bits_checked = 0; + if (buf[0] > (4 * 5 + 4) * 9 + 8) + return 0; + /* Most likely value in the first byte of LZMA stream. */ + if (buf[0] == 0x5d || buf[0] == 0x5e) + bits_checked += 8; + + /* Sixth through fourteenth bytes are uncompressed size, + * stored in little-endian order. `-1' means uncompressed + * size is unknown and lzma of XZ Utils always records `-1' + * in this field. */ + uncompressed_size = le64dec(buf+5); + if (uncompressed_size == (uint64_t)(-1)) + bits_checked += 64; + + /* Second through fifth bytes are dictionary size, stored in + * little-endian order. The minimum dictionary size is + * 1 << 12(4KiB) which the lzma of LZMA SDK uses with option + * -d12 and the maxinam dictionary size is 1 << 27(128MiB) + * which the one uses with option -d27. + * NOTE: A comment of LZMA SDK source code says this dictionary + * range is from 1 << 12 to 1 << 30. */ + dicsize = le32dec(buf+1); + switch (dicsize) + { + case 0x00001000:/* lzma of LZMA SDK option -d12. */ + case 0x00002000:/* lzma of LZMA SDK option -d13. */ + case 0x00004000:/* lzma of LZMA SDK option -d14. */ + case 0x00008000:/* lzma of LZMA SDK option -d15. */ + case 0x00010000:/* lzma of XZ Utils option -0 and -1. + * lzma of LZMA SDK option -d16. */ + case 0x00020000:/* lzma of LZMA SDK option -d17. */ + case 0x00040000:/* lzma of LZMA SDK option -d18. */ + case 0x00080000:/* lzma of XZ Utils option -2. + * lzma of LZMA SDK option -d19. */ + case 0x00100000:/* lzma of XZ Utils option -3. + * lzma of LZMA SDK option -d20. */ + case 0x00200000:/* lzma of XZ Utils option -4. + * lzma of LZMA SDK option -d21. */ + case 0x00400000:/* lzma of XZ Utils option -5. + * lzma of LZMA SDK option -d22. */ + case 0x00800000:/* lzma of XZ Utils option -6. + * lzma of LZMA SDK option -d23. */ + case 0x01000000:/* lzma of XZ Utils option -7. + * lzma of LZMA SDK option -d24. */ + case 0x02000000:/* lzma of XZ Utils option -8. + * lzma of LZMA SDK option -d25. */ + case 0x04000000:/* lzma of XZ Utils option -9. + * lzma of LZMA SDK option -d26. */ + case 0x08000000:/* lzma of LZMA SDK option -d27. */ + bits_checked += 32; + break; + default: + /* If a memory usage for encoding was not enough on + * the platform where LZMA stream was made, lzma of + * XZ Utils automatically decreased the dictionary + * size to enough memory for encoding by 1Mi bytes + * (1 << 20).*/ + if (dicsize <= 0x03F00000 && dicsize >= 0x00300000 + && (dicsize & ((1 << 20)-1)) == 0 + && bits_checked == 8 + 64) + { + bits_checked += 32; + break; + } + /* Otherwise dictionary size is unlikely. But it is + * possible that someone makes lzma stream with + * liblzma/LZMA SDK in one's dictionary size. */ + return 0; + } + + /* TODO: The above test is still very weak. It would be + * good to do better. */ + msg ("compress_xz::bid_lzma: success: %d\n", bits_checked); + return (bits_checked); +} + + diff --git a/compress_xz.h b/compress_xz.h new file mode 100644 index 00000000..07572ef2 --- /dev/null +++ b/compress_xz.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2010, Charles Wilson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + * Written by Charles Wilson + * + */ + +#ifndef SETUP_COMPRESS_XZ_H +#define SETUP_COMPRESS_XZ_H + +/* this is the parent class for all compress IO operations. + */ + +#include "compress.h" +#include + +class compress_xz:public compress +{ +public: + compress_xz (io_stream *); /* decompress (read) only */ + virtual ssize_t read (void *buffer, size_t len); + virtual ssize_t write (const void *buffer, size_t len); /* not implemented */ + virtual ssize_t peek (void *buffer, size_t len); + virtual long tell (); /* not implemented */ + virtual int seek (long where, io_stream_seek_t whence); /* not implemented */ + virtual int error (); + virtual const char *next_file_name () { return NULL; }; + virtual int set_mtime (time_t); + virtual time_t get_mtime (); + virtual mode_t get_mode (); + virtual size_t get_size () {return 0;}; + virtual ~compress_xz (); + virtual void init_decoder (void); + static bool is_xz_or_lzma (void *buffer, size_t len); + static int bid_xz (void *buffer, size_t len); + static int bid_lzma (void *buffer, size_t len); + virtual void release_original(); /* give up ownership of original io_stream */ + +private: + compress_xz () {}; + + io_stream *original; + bool owns_original; + char peekbuf[512]; + size_t peeklen; + int lasterr; + void destroy (); + + struct private_data { + lzma_stream stream; + unsigned char *out_block; + size_t out_block_size; + uint64_t total_out; + char eof; /* True = found end of compressed data. */ + unsigned char *in_block; + size_t in_block_size; + uint64_t total_in; + unsigned char *out_p; + size_t in_pos; + size_t out_pos; + size_t in_size; + size_t in_processed; + size_t out_processed; + }; + + typedef enum { + COMPRESSION_UNKNOWN = -1, + COMPRESSION_XZ, + COMPRESSION_LZMA + } compression_type_t; + + compression_type_t compression_type; + + static const size_t out_block_size = 64 * 1024; + static const size_t in_block_size = 64 * 1024; + struct private_data *state; +}; + +#endif /* SETUP_COMPRESS_XZ_H */ diff --git a/lzma-sdk/LzmaDec.c b/lzma-sdk/LzmaDec.c deleted file mode 100644 index aa38e91e..00000000 --- a/lzma-sdk/LzmaDec.c +++ /dev/null @@ -1,1014 +0,0 @@ -/* LzmaDec.c -- LZMA Decoder -2008-04-29 -Copyright (c) 1999-2008 Igor Pavlov -Read LzmaDec.h for license options */ - -#include "LzmaDec.h" - -#include - -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 - -#define RC_INIT_SIZE 5 - -#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } - -#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); -#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ - { UPDATE_0(p); i = (i + i); A0; } else \ - { UPDATE_1(p); i = (i + i) + 1; A1; } -#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) - -#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } -#define TREE_DECODE(probs, limit, i) \ - { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } - -/* #define _LZMA_SIZE_OPT */ - -#ifdef _LZMA_SIZE_OPT -#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) -#else -#define TREE_6_DECODE(probs, i) \ - { i = 1; \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - i -= 0x40; } -#endif - -#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } - -#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -#define UPDATE_0_CHECK range = bound; -#define UPDATE_1_CHECK range -= bound; code -= bound; -#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ - { UPDATE_0_CHECK; i = (i + i); A0; } else \ - { UPDATE_1_CHECK; i = (i + i) + 1; A1; } -#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) -#define TREE_DECODE_CHECK(probs, limit, i) \ - { i = 1; do { GET_BIT_CHECK(probs + i, i) } while(i < limit); i -= limit; } - - -#define kNumPosBitsMax 4 -#define kNumPosStatesMax (1 << kNumPosBitsMax) - -#define kLenNumLowBits 3 -#define kLenNumLowSymbols (1 << kLenNumLowBits) -#define kLenNumMidBits 3 -#define kLenNumMidSymbols (1 << kLenNumMidBits) -#define kLenNumHighBits 8 -#define kLenNumHighSymbols (1 << kLenNumHighBits) - -#define LenChoice 0 -#define LenChoice2 (LenChoice + 1) -#define LenLow (LenChoice2 + 1) -#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -#define kNumLenProbs (LenHigh + kLenNumHighSymbols) - - -#define kNumStates 12 -#define kNumLitStates 7 - -#define kStartPosModelIndex 4 -#define kEndPosModelIndex 14 -#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) - -#define kNumPosSlotBits 6 -#define kNumLenToPosStates 4 - -#define kNumAlignBits 4 -#define kAlignTableSize (1 << kNumAlignBits) - -#define kMatchMinLen 2 -#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) - -#define IsMatch 0 -#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -#define IsRepG0 (IsRep + kNumStates) -#define IsRepG1 (IsRepG0 + kNumStates) -#define IsRepG2 (IsRepG1 + kNumStates) -#define IsRep0Long (IsRepG2 + kNumStates) -#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -#define LenCoder (Align + kAlignTableSize) -#define RepLenCoder (LenCoder + kNumLenProbs) -#define Literal (RepLenCoder + kNumLenProbs) - -#define LZMA_BASE_SIZE 1846 -#define LZMA_LIT_SIZE 768 - -#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) - -#if Literal != LZMA_BASE_SIZE -StopCompilingDueBUG -#endif - -/* -#define LZMA_STREAM_WAS_FINISHED_ID (-1) -#define LZMA_SPEC_LEN_OFFSET (-3) -*/ - -Byte kLiteralNextStates[kNumStates * 2] = -{ - 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5, - 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 -}; - -#define LZMA_DIC_MIN (1 << 12) - -/* First LZMA-symbol is always decoded. -And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization -Out: - Result: - 0 - OK - 1 - Error - p->remainLen: - < kMatchSpecLenStart : normal remain - = kMatchSpecLenStart : finished - = kMatchSpecLenStart + 1 : Flush marker - = kMatchSpecLenStart + 2 : State Init Marker -*/ - -static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -{ - CLzmaProb *probs = p->probs; - - unsigned state = p->state; - UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; - unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; - unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; - unsigned lc = p->prop.lc; - - Byte *dic = p->dic; - SizeT dicBufSize = p->dicBufSize; - SizeT dicPos = p->dicPos; - - UInt32 processedPos = p->processedPos; - UInt32 checkDicSize = p->checkDicSize; - unsigned len = 0; - - const Byte *buf = p->buf; - UInt32 range = p->range; - UInt32 code = p->code; - - do - { - CLzmaProb *prob; - UInt32 bound; - unsigned ttt; - unsigned posState = processedPos & pbMask; - - prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; - IF_BIT_0(prob) - { - unsigned symbol; - UPDATE_0(prob); - prob = probs + Literal; - if (checkDicSize != 0 || processedPos != 0) - prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + - (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); - - if (state < kNumLitStates) - { - symbol = 1; - do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); - } - else - { - unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; - unsigned offs = 0x100; - symbol = 1; - do - { - unsigned bit; - CLzmaProb *probLit; - matchByte <<= 1; - bit = (matchByte & offs); - probLit = prob + offs + bit + symbol; - GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) - } - while (symbol < 0x100); - } - dic[dicPos++] = (Byte)symbol; - processedPos++; - - state = kLiteralNextStates[state]; - /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */ - continue; - } - else - { - UPDATE_1(prob); - prob = probs + IsRep + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - state += kNumStates; - prob = probs + LenCoder; - } - else - { - UPDATE_1(prob); - if (checkDicSize == 0 && processedPos == 0) - return SZ_ERROR_DATA; - prob = probs + IsRepG0 + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; - IF_BIT_0(prob) - { - UPDATE_0(prob); - dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; - dicPos++; - processedPos++; - state = state < kNumLitStates ? 9 : 11; - continue; - } - UPDATE_1(prob); - } - else - { - UInt32 distance; - UPDATE_1(prob); - prob = probs + IsRepG1 + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - distance = rep1; - } - else - { - UPDATE_1(prob); - prob = probs + IsRepG2 + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - distance = rep2; - } - else - { - UPDATE_1(prob); - distance = rep3; - rep3 = rep2; - } - rep2 = rep1; - } - rep1 = rep0; - rep0 = distance; - } - state = state < kNumLitStates ? 8 : 11; - prob = probs + RepLenCoder; - } - { - unsigned limit, offset; - CLzmaProb *probLen = prob + LenChoice; - IF_BIT_0(probLen) - { - UPDATE_0(probLen); - probLen = prob + LenLow + (posState << kLenNumLowBits); - offset = 0; - limit = (1 << kLenNumLowBits); - } - else - { - UPDATE_1(probLen); - probLen = prob + LenChoice2; - IF_BIT_0(probLen) - { - UPDATE_0(probLen); - probLen = prob + LenMid + (posState << kLenNumMidBits); - offset = kLenNumLowSymbols; - limit = (1 << kLenNumMidBits); - } - else - { - UPDATE_1(probLen); - probLen = prob + LenHigh; - offset = kLenNumLowSymbols + kLenNumMidSymbols; - limit = (1 << kLenNumHighBits); - } - } - TREE_DECODE(probLen, limit, len); - len += offset; - } - - if (state >= kNumStates) - { - UInt32 distance; - prob = probs + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); - TREE_6_DECODE(prob, distance); - if (distance >= kStartPosModelIndex) - { - unsigned posSlot = (unsigned)distance; - int numDirectBits = (int)(((distance >> 1) - 1)); - distance = (2 | (distance & 1)); - if (posSlot < kEndPosModelIndex) - { - distance <<= numDirectBits; - prob = probs + SpecPos + distance - posSlot - 1; - { - UInt32 mask = 1; - unsigned i = 1; - do - { - GET_BIT2(prob + i, i, ; , distance |= mask); - mask <<= 1; - } - while(--numDirectBits != 0); - } - } - else - { - numDirectBits -= kNumAlignBits; - do - { - NORMALIZE - range >>= 1; - - { - UInt32 t; - code -= range; - t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ - distance = (distance << 1) + (t + 1); - code += range & t; - } - /* - distance <<= 1; - if (code >= range) - { - code -= range; - distance |= 1; - } - */ - } - while (--numDirectBits != 0); - prob = probs + Align; - distance <<= kNumAlignBits; - { - unsigned i = 1; - GET_BIT2(prob + i, i, ; , distance |= 1); - GET_BIT2(prob + i, i, ; , distance |= 2); - GET_BIT2(prob + i, i, ; , distance |= 4); - GET_BIT2(prob + i, i, ; , distance |= 8); - } - if (distance == (UInt32)0xFFFFFFFF) - { - len += kMatchSpecLenStart; - state -= kNumStates; - break; - } - } - } - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - rep0 = distance + 1; - if (checkDicSize == 0) - { - if (distance >= processedPos) - return SZ_ERROR_DATA; - } - else if (distance >= checkDicSize) - return SZ_ERROR_DATA; - state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; - /* state = kLiteralNextStates[state]; */ - } - - len += kMatchMinLen; - - { - SizeT rem = limit - dicPos; - unsigned curLen = ((rem < len) ? (unsigned)rem : len); - SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); - - processedPos += curLen; - - len -= curLen; - if (pos + curLen <= dicBufSize) - { - Byte *dest = dic + dicPos; - ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; - const Byte *lim = dest + curLen; - dicPos += curLen; - do - *(dest) = (Byte)*(dest + src); - while (++dest != lim); - } - else - { - do - { - dic[dicPos++] = dic[pos]; - if (++pos == dicBufSize) - pos = 0; - } - while (--curLen != 0); - } - } - } - } - while (dicPos < limit && buf < bufLimit); - NORMALIZE; - p->buf = buf; - p->range = range; - p->code = code; - p->remainLen = len; - p->dicPos = dicPos; - p->processedPos = processedPos; - p->reps[0] = rep0; - p->reps[1] = rep1; - p->reps[2] = rep2; - p->reps[3] = rep3; - p->state = state; - - return SZ_OK; -} - -static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) -{ - if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) - { - Byte *dic = p->dic; - SizeT dicPos = p->dicPos; - SizeT dicBufSize = p->dicBufSize; - unsigned len = p->remainLen; - UInt32 rep0 = p->reps[0]; - if (limit - dicPos < len) - len = (unsigned)(limit - dicPos); - - if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) - p->checkDicSize = p->prop.dicSize; - - p->processedPos += len; - p->remainLen -= len; - while (len-- != 0) - { - dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; - dicPos++; - } - p->dicPos = dicPos; - } -} - -/* LzmaDec_DecodeReal2 decodes LZMA-symbols and sets p->needFlush and p->needInit, if required. */ - -static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -{ - do - { - SizeT limit2 = limit; - if (p->checkDicSize == 0) - { - UInt32 rem = p->prop.dicSize - p->processedPos; - if (limit - p->dicPos > rem) - limit2 = p->dicPos + rem; - } - RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); - if (p->processedPos >= p->prop.dicSize) - p->checkDicSize = p->prop.dicSize; - LzmaDec_WriteRem(p, limit); - } - while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); - - if (p->remainLen > kMatchSpecLenStart) - { - p->remainLen = kMatchSpecLenStart; - } - return 0; -} - -typedef enum -{ - DUMMY_ERROR, /* unexpected end of input stream */ - DUMMY_LIT, - DUMMY_MATCH, - DUMMY_REP -} ELzmaDummy; - -static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) -{ - UInt32 range = p->range; - UInt32 code = p->code; - const Byte *bufLimit = buf + inSize; - CLzmaProb *probs = p->probs; - unsigned state = p->state; - ELzmaDummy res; - - { - CLzmaProb *prob; - UInt32 bound; - unsigned ttt; - unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); - - prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK - - /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ - - prob = probs + Literal; - if (p->checkDicSize != 0 || p->processedPos != 0) - prob += (LZMA_LIT_SIZE * - ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + - (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); - - if (state < kNumLitStates) - { - unsigned symbol = 1; - do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); - } - else - { - unsigned matchByte = p->dic[p->dicPos - p->reps[0] + - ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; - unsigned offs = 0x100; - unsigned symbol = 1; - do - { - unsigned bit; - CLzmaProb *probLit; - matchByte <<= 1; - bit = (matchByte & offs); - probLit = prob + offs + bit + symbol; - GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) - } - while (symbol < 0x100); - } - res = DUMMY_LIT; - } - else - { - unsigned len; - UPDATE_1_CHECK; - - prob = probs + IsRep + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - state = 0; - prob = probs + LenCoder; - res = DUMMY_MATCH; - } - else - { - UPDATE_1_CHECK; - res = DUMMY_REP; - prob = probs + IsRepG0 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - NORMALIZE_CHECK; - return DUMMY_REP; - } - else - { - UPDATE_1_CHECK; - } - } - else - { - UPDATE_1_CHECK; - prob = probs + IsRepG1 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - } - else - { - UPDATE_1_CHECK; - prob = probs + IsRepG2 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - } - else - { - UPDATE_1_CHECK; - } - } - } - state = kNumStates; - prob = probs + RepLenCoder; - } - { - unsigned limit, offset; - CLzmaProb *probLen = prob + LenChoice; - IF_BIT_0_CHECK(probLen) - { - UPDATE_0_CHECK; - probLen = prob + LenLow + (posState << kLenNumLowBits); - offset = 0; - limit = 1 << kLenNumLowBits; - } - else - { - UPDATE_1_CHECK; - probLen = prob + LenChoice2; - IF_BIT_0_CHECK(probLen) - { - UPDATE_0_CHECK; - probLen = prob + LenMid + (posState << kLenNumMidBits); - offset = kLenNumLowSymbols; - limit = 1 << kLenNumMidBits; - } - else - { - UPDATE_1_CHECK; - probLen = prob + LenHigh; - offset = kLenNumLowSymbols + kLenNumMidSymbols; - limit = 1 << kLenNumHighBits; - } - } - TREE_DECODE_CHECK(probLen, limit, len); - len += offset; - } - - if (state < 4) - { - unsigned posSlot; - prob = probs + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << - kNumPosSlotBits); - TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); - if (posSlot >= kStartPosModelIndex) - { - int numDirectBits = ((posSlot >> 1) - 1); - - /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ - - if (posSlot < kEndPosModelIndex) - { - prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; - } - else - { - numDirectBits -= kNumAlignBits; - do - { - NORMALIZE_CHECK - range >>= 1; - code -= range & (((code - range) >> 31) - 1); - /* if (code >= range) code -= range; */ - } - while (--numDirectBits != 0); - prob = probs + Align; - numDirectBits = kNumAlignBits; - } - { - unsigned i = 1; - do - { - GET_BIT_CHECK(prob + i, i); - } - while(--numDirectBits != 0); - } - } - } - } - } - NORMALIZE_CHECK; - return res; -} - - -static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) -{ - p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); - p->range = 0xFFFFFFFF; - p->needFlush = 0; -} - -static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -{ - p->needFlush = 1; - p->remainLen = 0; - p->tempBufSize = 0; - - if (initDic) - { - p->processedPos = 0; - p->checkDicSize = 0; - p->needInitState = 1; - } - if (initState) - p->needInitState = 1; -} - -void LzmaDec_Init(CLzmaDec *p) -{ - p->dicPos = 0; - LzmaDec_InitDicAndState(p, True, True); -} - -static void LzmaDec_InitStateReal(CLzmaDec *p) -{ - UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); - UInt32 i; - CLzmaProb *probs = p->probs; - for (i = 0; i < numProbs; i++) - probs[i] = kBitModelTotal >> 1; - p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; - p->state = 0; - p->needInitState = 0; -} - -SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, - ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - SizeT inSize = *srcLen; - (*srcLen) = 0; - LzmaDec_WriteRem(p, dicLimit); - - *status = LZMA_STATUS_NOT_SPECIFIED; - - while (p->remainLen != kMatchSpecLenStart) - { - int checkEndMarkNow; - - if (p->needFlush != 0) - { - for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) - p->tempBuf[p->tempBufSize++] = *src++; - if (p->tempBufSize < RC_INIT_SIZE) - { - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (p->tempBuf[0] != 0) - return SZ_ERROR_DATA; - - LzmaDec_InitRc(p, p->tempBuf); - p->tempBufSize = 0; - } - - checkEndMarkNow = 0; - if (p->dicPos >= dicLimit) - { - if (p->remainLen == 0 && p->code == 0) - { - *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; - return SZ_OK; - } - if (finishMode == LZMA_FINISH_ANY) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_OK; - } - if (p->remainLen != 0) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - checkEndMarkNow = 1; - } - - if (p->needInitState) - LzmaDec_InitStateReal(p); - - if (p->tempBufSize == 0) - { - SizeT processed; - const Byte *bufLimit; - if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) - { - int dummyRes = LzmaDec_TryDummy(p, src, inSize); - if (dummyRes == DUMMY_ERROR) - { - memcpy(p->tempBuf, src, inSize); - p->tempBufSize = (unsigned)inSize; - (*srcLen) += inSize; - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (checkEndMarkNow && dummyRes != DUMMY_MATCH) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - bufLimit = src; - } - else - bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; - p->buf = src; - if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) - return SZ_ERROR_DATA; - processed = p->buf - src; - (*srcLen) += processed; - src += processed; - inSize -= processed; - } - else - { - unsigned rem = p->tempBufSize, lookAhead = 0; - while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) - p->tempBuf[rem++] = src[lookAhead++]; - p->tempBufSize = rem; - if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) - { - int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); - if (dummyRes == DUMMY_ERROR) - { - (*srcLen) += lookAhead; - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (checkEndMarkNow && dummyRes != DUMMY_MATCH) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - } - p->buf = p->tempBuf; - if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) - return SZ_ERROR_DATA; - lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); - (*srcLen) += lookAhead; - src += lookAhead; - inSize -= lookAhead; - p->tempBufSize = 0; - } - } - if (p->code == 0) - *status = LZMA_STATUS_FINISHED_WITH_MARK; - return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; -} - -SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - SizeT outSize = *destLen; - SizeT inSize = *srcLen; - *srcLen = *destLen = 0; - for (;;) - { - SizeT inSizeCur = inSize, outSizeCur, dicPos; - ELzmaFinishMode curFinishMode; - SRes res; - if (p->dicPos == p->dicBufSize) - p->dicPos = 0; - dicPos = p->dicPos; - if (outSize > p->dicBufSize - dicPos) - { - outSizeCur = p->dicBufSize; - curFinishMode = LZMA_FINISH_ANY; - } - else - { - outSizeCur = dicPos + outSize; - curFinishMode = finishMode; - } - - res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); - src += inSizeCur; - inSize -= inSizeCur; - *srcLen += inSizeCur; - outSizeCur = p->dicPos - dicPos; - memcpy(dest, p->dic + dicPos, outSizeCur); - dest += outSizeCur; - outSize -= outSizeCur; - *destLen += outSizeCur; - if (res != 0) - return res; - if (outSizeCur == 0 || outSize == 0) - return SZ_OK; - } -} - -void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->probs); - p->probs = 0; -} - -static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->dic); - p->dic = 0; -} - -void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) -{ - LzmaDec_FreeProbs(p, alloc); - LzmaDec_FreeDict(p, alloc); -} - -SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) -{ - UInt32 dicSize; - Byte d; - - if (size < LZMA_PROPS_SIZE) - return SZ_ERROR_UNSUPPORTED; - else - dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); - - if (dicSize < LZMA_DIC_MIN) - dicSize = LZMA_DIC_MIN; - p->dicSize = dicSize; - - d = data[0]; - if (d >= (9 * 5 * 5)) - return SZ_ERROR_UNSUPPORTED; - - p->lc = d % 9; - d /= 9; - p->pb = d / 5; - p->lp = d % 5; - - return SZ_OK; -} - -static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) -{ - UInt32 numProbs = LzmaProps_GetNumProbs(propNew); - if (p->probs == 0 || numProbs != p->numProbs) - { - LzmaDec_FreeProbs(p, alloc); - p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); - p->numProbs = numProbs; - if (p->probs == 0) - return SZ_ERROR_MEM; - } - return SZ_OK; -} - -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -{ - CLzmaProps propNew; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); - p->prop = propNew; - return SZ_OK; -} - -SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -{ - CLzmaProps propNew; - SizeT dicBufSize; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); - dicBufSize = propNew.dicSize; - if (p->dic == 0 || dicBufSize != p->dicBufSize) - { - LzmaDec_FreeDict(p, alloc); - p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); - if (p->dic == 0) - { - LzmaDec_FreeProbs(p, alloc); - return SZ_ERROR_MEM; - } - } - p->dicBufSize = dicBufSize; - p->prop = propNew; - return SZ_OK; -} - -SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc) -{ - CLzmaDec p; - SRes res; - SizeT inSize = *srcLen; - SizeT outSize = *destLen; - *srcLen = *destLen = 0; - if (inSize < RC_INIT_SIZE) - return SZ_ERROR_INPUT_EOF; - - LzmaDec_Construct(&p); - res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); - if (res != 0) - return res; - p.dic = dest; - p.dicBufSize = outSize; - - LzmaDec_Init(&p); - - *srcLen = inSize; - res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); - - if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) - res = SZ_ERROR_INPUT_EOF; - - (*destLen) = p.dicPos; - LzmaDec_FreeProbs(&p, alloc); - return res; -} diff --git a/lzma-sdk/LzmaDec.h b/lzma-sdk/LzmaDec.h deleted file mode 100644 index d084047b..00000000 --- a/lzma-sdk/LzmaDec.h +++ /dev/null @@ -1,241 +0,0 @@ -/* LzmaDec.h -- LZMA Decoder -2008-04-29 -Copyright (c) 1999-2008 Igor Pavlov -You can use any of the following license options: - 1) GNU Lesser General Public License (GNU LGPL) - 2) Common Public License (CPL) - 3) Common Development and Distribution License (CDDL) Version 1.0 - 4) Igor Pavlov, as the author of this code, expressly permits you to - statically or dynamically link your code (or bind by name) to this file, - while you keep this file unmodified. -*/ - -#ifndef __LZMADEC_H -#define __LZMADEC_H - -#include "Types.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* #define _LZMA_PROB32 */ -/* _LZMA_PROB32 can increase the speed on some CPUs, - but memory usage for CLzmaDec::probs will be doubled in that case */ - -#ifdef _LZMA_PROB32 -#define CLzmaProb UInt32 -#else -#define CLzmaProb UInt16 -#endif - - -/* ---------- LZMA Properties ---------- */ - -#define LZMA_PROPS_SIZE 5 - -typedef struct _CLzmaProps -{ - unsigned lc, lp, pb; - UInt32 dicSize; -} CLzmaProps; - -/* LzmaProps_Decode - decodes properties -Returns: - SZ_OK - SZ_ERROR_UNSUPPORTED - Unsupported properties -*/ - -SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); - - -/* ---------- LZMA Decoder state ---------- */ - -/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. - Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ - -#define LZMA_REQUIRED_INPUT_MAX 20 - -typedef struct -{ - CLzmaProps prop; - CLzmaProb *probs; - Byte *dic; - const Byte *buf; - UInt32 range, code; - SizeT dicPos; - SizeT dicBufSize; - UInt32 processedPos; - UInt32 checkDicSize; - unsigned state; - UInt32 reps[4]; - unsigned remainLen; - int needFlush; - int needInitState; - UInt32 numProbs; - unsigned tempBufSize; - Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; -} CLzmaDec; - -#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } - -void LzmaDec_Init(CLzmaDec *p); - -/* There are two types of LZMA streams: - 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. - 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ - -typedef enum -{ - LZMA_FINISH_ANY, /* finish at any point */ - LZMA_FINISH_END /* block must be finished at the end */ -} ELzmaFinishMode; - -/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! - - You must use LZMA_FINISH_END, when you know that current output buffer - covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. - - If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, - and output value of destLen will be less than output buffer size limit. - You can check status result also. - - You can use multiple checks to test data integrity after full decompression: - 1) Check Result and "status" variable. - 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. - 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. - You must use correct finish mode in that case. */ - -typedef enum -{ - LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ - LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ - LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ - LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ - LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ -} ELzmaStatus; - -/* ELzmaStatus is used only as output value for function call */ - - -/* ---------- Interfaces ---------- */ - -/* There are 3 levels of interfaces: - 1) Dictionary Interface - 2) Buffer Interface - 3) One Call Interface - You can select any of these interfaces, but don't mix functions from different - groups for same object. */ - - -/* There are two variants to allocate state for Dictionary Interface: - 1) LzmaDec_Allocate / LzmaDec_Free - 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs - You can use variant 2, if you set dictionary buffer manually. - For Buffer Interface you must always use variant 1. - -LzmaDec_Allocate* can return: - SZ_OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - Unsupported properties -*/ - -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); -void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); - -SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); -void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); - -/* ---------- Dictionary Interface ---------- */ - -/* You can use it, if you want to eliminate the overhead for data copying from - dictionary to some other external buffer. - You must work with CLzmaDec variables directly in this interface. - - STEPS: - LzmaDec_Constr() - LzmaDec_Allocate() - for (each new stream) - { - LzmaDec_Init() - while (it needs more decompression) - { - LzmaDec_DecodeToDic() - use data from CLzmaDec::dic and update CLzmaDec::dicPos - } - } - LzmaDec_Free() -*/ - -/* LzmaDec_DecodeToDic - - The decoding to internal dictionary buffer (CLzmaDec::dic). - You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! - -finishMode: - It has meaning only if the decoding reaches output limit (dicLimit). - LZMA_FINISH_ANY - Decode just dicLimit bytes. - LZMA_FINISH_END - Stream must be finished after dicLimit. - -Returns: - SZ_OK - status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - LZMA_STATUS_NEEDS_MORE_INPUT - LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK - SZ_ERROR_DATA - Data error -*/ - -SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - - -/* ---------- Buffer Interface ---------- */ - -/* It's zlib-like interface. - See LzmaDec_DecodeToDic description for information about STEPS and return results, - but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need - to work with CLzmaDec variables manually. - -finishMode: - It has meaning only if the decoding reaches output limit (*destLen). - LZMA_FINISH_ANY - Decode just destLen bytes. - LZMA_FINISH_END - Stream must be finished after (*destLen). -*/ - -SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - - -/* ---------- One Call Interface ---------- */ - -/* LzmaDecode - -finishMode: - It has meaning only if the decoding reaches output limit (*destLen). - LZMA_FINISH_ANY - Decode just destLen bytes. - LZMA_FINISH_END - Stream must be finished after (*destLen). - -Returns: - SZ_OK - status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - Unsupported properties - SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). -*/ - -SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc); - -#ifdef __cplusplus -} /* end extern "C" */ -#endif - -#endif diff --git a/lzma-sdk/Types.h b/lzma-sdk/Types.h deleted file mode 100644 index 1d34f0c7..00000000 --- a/lzma-sdk/Types.h +++ /dev/null @@ -1,140 +0,0 @@ -/* Types.h -- Basic types -2008-04-11 -Igor Pavlov -Public domain */ - -#ifndef __7Z_TYPES_H -#define __7Z_TYPES_H - -#ifdef __cplusplus -extern "C" -{ -#endif - - -#define SZ_OK 0 - -#define SZ_ERROR_DATA 1 -#define SZ_ERROR_MEM 2 -#define SZ_ERROR_CRC 3 -#define SZ_ERROR_UNSUPPORTED 4 -#define SZ_ERROR_PARAM 5 -#define SZ_ERROR_INPUT_EOF 6 -#define SZ_ERROR_OUTPUT_EOF 7 -#define SZ_ERROR_READ 8 -#define SZ_ERROR_WRITE 9 -#define SZ_ERROR_PROGRESS 10 -#define SZ_ERROR_FAIL 11 -#define SZ_ERROR_THREAD 12 - -#define SZ_ERROR_ARCHIVE 16 -#define SZ_ERROR_NO_ARCHIVE 17 - -typedef int SRes; - -#ifndef RINOK -#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } -#endif - -typedef unsigned char Byte; -typedef short Int16; -typedef unsigned short UInt16; - -#ifdef _LZMA_UINT32_IS_ULONG -typedef long Int32; -typedef unsigned long UInt32; -#else -typedef int Int32; -typedef unsigned int UInt32; -#endif - -/* #define _SZ_NO_INT_64 */ -/* define it if your compiler doesn't support 64-bit integers */ - -#ifdef _SZ_NO_INT_64 - -typedef long Int64; -typedef unsigned long UInt64; - -#else - -#if defined(_MSC_VER) || defined(__BORLANDC__) -typedef __int64 Int64; -typedef unsigned __int64 UInt64; -#else -typedef long long int Int64; -typedef unsigned long long int UInt64; -#endif - -#endif - -#ifdef _LZMA_NO_SYSTEM_SIZE_T -typedef UInt32 SizeT; -#else -#include -typedef size_t SizeT; -#endif - -typedef int Bool; -#define True 1 -#define False 0 - - -#ifdef _MSC_VER - -#if _MSC_VER >= 1300 -#define MY_NO_INLINE __declspec(noinline) -#else -#define MY_NO_INLINE -#endif - -#define MY_CDECL __cdecl -#define MY_STD_CALL __stdcall -#define MY_FAST_CALL MY_NO_INLINE __fastcall - -#else - -#define MY_CDECL -#define MY_STD_CALL -#define MY_FAST_CALL - -#endif - - -/* The following interfaces use first parameter as pointer to structure */ - -typedef struct -{ - SRes (*Read)(void *p, void *buf, size_t *size); - /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. - (output(*size) < input(*size)) is allowed */ -} ISeqInStream; - -typedef struct -{ - size_t (*Write)(void *p, const void *buf, size_t size); - /* Returns: result - the number of actually written bytes. - (result < size) means error */ -} ISeqOutStream; - -typedef struct -{ - SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); - /* Returns: result. (result != SZ_OK) means break. - Value (UInt64)(Int64)-1 for size means unknown value. */ -} ICompressProgress; - -typedef struct -{ - void *(*Alloc)(void *p, size_t size); - void (*Free)(void *p, void *address); /* address can be 0 */ -} ISzAlloc; - -#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) -#define IAlloc_Free(p, a) (p)->Free((p), a) - -#ifdef __cplusplus -} /* end extern "C" */ -#endif - -#endif -- 2.43.5