+2010-03-14 Charles Wilson <cygwin@cwilson.fastmail.fm>
+
+ 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 <dj@redhat.com>
* nio-ftp.c (read): Read RETR status code on EOF to avoid
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@
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 \
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 \
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)
#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.
* 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)
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 */
+++ /dev/null
-/*
- * 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 <cygwin@cygwin.com>
- *
- */
-
-#include "compress_lzma.h"
-
-#include <stdexcept>
-using namespace std;
-#include <errno.h>
-#include <memory.h>
-#include <malloc.h>
-
-/*
- * 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;
-}
-
+++ /dev/null
-/*
- * 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 <cygwin@cygwin.com>
- *
- */
-
-#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 */
--- /dev/null
+/*
+ * 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 <cygwin@cygwin.com>
+ *
+ * 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 <stdexcept>
+using namespace std;
+#include <errno.h>
+#include <memory.h>
+#include <malloc.h>
+
+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);
+}
+
+
--- /dev/null
+/*
+ * 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 <cygwin@cygwin.com>
+ *
+ */
+
+#ifndef SETUP_COMPRESS_XZ_H
+#define SETUP_COMPRESS_XZ_H
+
+/* this is the parent class for all compress IO operations.
+ */
+
+#include "compress.h"
+#include <lzma.h>
+
+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 */
+++ /dev/null
-/* LzmaDec.c -- LZMA Decoder
-2008-04-29
-Copyright (c) 1999-2008 Igor Pavlov
-Read LzmaDec.h for license options */
-
-#include "LzmaDec.h"
-
-#include <string.h>
-
-#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;
-}
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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 <stddef.h>
-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