Created
October 19, 2013 05:53
-
-
Save nemequ/7052084 to your computer and use it in GitHub Desktop.
Add lzmasdk plugin. Currently, this plugin only supports the ppmd7 codec. Signed-off-by: Evan Nemerson <evan@coeus-group.com>
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 416fb2832781829ed431a409014359cb23f3004e Mon Sep 17 00:00:00 2001 | |
From: Evan Nemerson <evan@coeus-group.com> | |
Date: Fri, 18 Oct 2013 19:39:31 -0700 | |
Subject: [PATCH] Add lzmasdk plugin. | |
Currently, this plugin only supports the ppmd7 codec. | |
Signed-off-by: Evan Nemerson <evan@coeus-group.com> | |
--- | |
.gitmodules | 3 + | |
configure.ac | 3 +- | |
plugins/Makefile.am | 1 + | |
plugins/lzmasdk/Makefile.am | 43 ++++ | |
plugins/lzmasdk/lzma-sdk | 1 + | |
plugins/lzmasdk/lzmasdk.codecs | 1 + | |
plugins/lzmasdk/lzmasdk.m4 | 5 + | |
plugins/lzmasdk/lzmasdk.md | 22 +++ | |
plugins/lzmasdk/squash-lzmasdk.c | 418 +++++++++++++++++++++++++++++++++++++++ | |
9 files changed, 496 insertions(+), 1 deletion(-) | |
create mode 100644 plugins/lzmasdk/Makefile.am | |
create mode 160000 plugins/lzmasdk/lzma-sdk | |
create mode 100644 plugins/lzmasdk/lzmasdk.codecs | |
create mode 100644 plugins/lzmasdk/lzmasdk.m4 | |
create mode 100644 plugins/lzmasdk/lzmasdk.md | |
create mode 100644 plugins/lzmasdk/squash-lzmasdk.c | |
diff --git a/.gitmodules b/.gitmodules | |
index da0488d..8a96ad0 100644 | |
--- a/.gitmodules | |
+++ b/.gitmodules | |
@@ -31,3 +31,6 @@ | |
[submodule "plugins/lzjb/lzjb"] | |
path = plugins/lzjb/lzjb | |
url = https://github.com/nemequ/lzjb.git | |
+[submodule "plugins/lzmasdk/lzma-sdk"] | |
+ path = plugins/lzmasdk/lzma-sdk | |
+ url = https://github.com/nemequ/lzma-sdk.git | |
diff --git a/configure.ac b/configure.ac | |
index 9079787..d88d656 100644 | |
--- a/configure.ac | |
+++ b/configure.ac | |
@@ -192,7 +192,7 @@ AC_SUBST(PLUGIN_LIBTOOL_FLAGS) | |
SQUASH_PLUGINS="" | |
SQUASH_PLUGINS_ENABLED="" | |
-m4_foreach([plugin],[blosc, bzip2, doboz, fastlz, ipp, lz4, lzg, lzma, lzmat, lzf, lzjb, lzo, quicklz, sharc, snappy, wflz, zlib, zpaq], [ | |
+m4_foreach([plugin],[blosc, bzip2, doboz, fastlz, ipp, lz4, lzg, lzma, lzmasdk, lzmat, lzf, lzjb, lzo, quicklz, sharc, snappy, wflz, zlib, zpaq], [ | |
m4_include(plugins/plugin/plugin[.m4]) | |
SQUASH_PLUGINS="${SQUASH_PLUGINS} plugin" | |
]) | |
@@ -267,6 +267,7 @@ AC_CONFIG_FILES([Makefile | |
plugins/ipp/Makefile | |
plugins/lz4/Makefile | |
plugins/lzma/Makefile | |
+ plugins/lzmasdk/Makefile | |
plugins/lzmat/Makefile | |
plugins/lzf/Makefile | |
plugins/lzg/Makefile | |
diff --git a/plugins/Makefile.am b/plugins/Makefile.am | |
index 01f0d19..4599567 100644 | |
--- a/plugins/Makefile.am | |
+++ b/plugins/Makefile.am | |
@@ -6,6 +6,7 @@ SUBDIRS = \ | |
ipp \ | |
lz4 \ | |
lzma \ | |
+ lzmasdk \ | |
lzmat \ | |
lzf \ | |
lzg \ | |
diff --git a/plugins/lzmasdk/Makefile.am b/plugins/lzmasdk/Makefile.am | |
new file mode 100644 | |
index 0000000..e1b5caf | |
--- /dev/null | |
+++ b/plugins/lzmasdk/Makefile.am | |
@@ -0,0 +1,43 @@ | |
+COMMON_CFLAGS = \ | |
+ -O3 \ | |
+ -I$(top_srcdir) \ | |
+ @WARN_CFLAGS@ \ | |
+ -Wno-missing-prototypes \ | |
+ -Wno-strict-prototypes \ | |
+ -DSQUASH_IS_UNSTABLE | |
+ | |
+COMMON_LIBS = $(top_builddir)/squash/libsquash@SQUASH_API_VERSION@.la | |
+ | |
+LZMA_SDK_FILES = \ | |
+ lzma-sdk/C/Ppmd7.c \ | |
+ lzma-sdk/C/Ppmd7Dec.c \ | |
+ lzma-sdk/C/Ppmd7Enc.c | |
+ | |
+if ENABLE_LZMA_SDK | |
+ | |
+plugindir = $(libdir)/squash/@SQUASH_API_VERSION@/plugins/lzmasdk | |
+plugin_DATA = lzmasdk.codecs | |
+ | |
+plugin_LTLIBRARIES = \ | |
+ libsquash@SQUASH_API_VERSION@-plugin-lzmasdk.la | |
+ | |
+endif | |
+ | |
+libsquash@SQUASH_API_VERSION@_plugin_lzmasdk_la_CFLAGS = \ | |
+ $(COMMON_CFLAGS) | |
+ | |
+libsquash@SQUASH_API_VERSION@_plugin_lzmasdk_la_LDFLAGS = \ | |
+ $(PLUGIN_LIBTOOL_FLAGS) | |
+ | |
+libsquash@SQUASH_API_VERSION@_plugin_lzmasdk_la_LIBADD = \ | |
+ $(COMMON_LIBS) | |
+ | |
+libsquash@SQUASH_API_VERSION@_plugin_lzmasdk_la_SOURCES = \ | |
+ squash-lzmasdk.c \ | |
+ $(LZMA_SDK_FILES) | |
+ | |
+EXTRA_DIST = \ | |
+ $(plugin_DATA) \ | |
+ lzmasdk.md | |
+ | |
+include $(top_srcdir)/git.mk | |
diff --git a/plugins/lzmasdk/lzma-sdk b/plugins/lzmasdk/lzma-sdk | |
new file mode 160000 | |
index 0000000..f6d1390 | |
--- /dev/null | |
+++ b/plugins/lzmasdk/lzma-sdk | |
@@ -0,0 +1 @@ | |
+Subproject commit f6d13902e415422d9b4d7ad62b89a2c1cee4bd41 | |
diff --git a/plugins/lzmasdk/lzmasdk.codecs b/plugins/lzmasdk/lzmasdk.codecs | |
new file mode 100644 | |
index 0000000..5fbc25c | |
--- /dev/null | |
+++ b/plugins/lzmasdk/lzmasdk.codecs | |
@@ -0,0 +1 @@ | |
+[ppmd7] | |
diff --git a/plugins/lzmasdk/lzmasdk.m4 b/plugins/lzmasdk/lzmasdk.m4 | |
new file mode 100644 | |
index 0000000..9704577 | |
--- /dev/null | |
+++ b/plugins/lzmasdk/lzmasdk.m4 | |
@@ -0,0 +1,5 @@ | |
+AC_ARG_ENABLE([lzmasdk], | |
+ [AC_HELP_STRING([--enable-lzmasdk=@<:@yes/no@:>@], [Enable lzmasdk plugin @<:@default=yes@:>@])],, | |
+ [enable_lzmasdk=yes]) | |
+ | |
+AM_CONDITIONAL([ENABLE_LZMA_SDK], test x$enable_lzmasdk = "xyes") | |
diff --git a/plugins/lzmasdk/lzmasdk.md b/plugins/lzmasdk/lzmasdk.md | |
new file mode 100644 | |
index 0000000..22346ff | |
--- /dev/null | |
+++ b/plugins/lzmasdk/lzmasdk.md | |
@@ -0,0 +1,22 @@ | |
+# lzmasdk Plugin # | |
+ | |
+LZMA SDK is the software development kit for the popular 7-zip project. | |
+ | |
+For more information about the LZMA SDK, see http://www.7-zip.org/sdk.html | |
+ | |
+## Codecs ## | |
+ | |
+- **ppmd7** — The variant of PPMD used in 7zip, which is PPMD h with | |
+ the range coder from 7z instead of the original, making it | |
+ incompatible with the original PPMD h. | |
+ | |
+## Options ## | |
+ | |
+- **memory** (integer, 2048 - 4294967259, default 16777216) | |
+- **max-order** (integer, 2 - 64, default 6) | |
+ | |
+## License ## | |
+ | |
+The lzmasdk plugin is licensed under the [MIT | |
+License](http://opensource.org/licenses/MIT), and the LZMA SDK is | |
+public domain. | |
diff --git a/plugins/lzmasdk/squash-lzmasdk.c b/plugins/lzmasdk/squash-lzmasdk.c | |
new file mode 100644 | |
index 0000000..8d8e80b | |
--- /dev/null | |
+++ b/plugins/lzmasdk/squash-lzmasdk.c | |
@@ -0,0 +1,418 @@ | |
+/* Copyright (c) 2013 The Squash Authors | |
+ * | |
+ * Permission is hereby granted, free of charge, to any person | |
+ * obtaining a copy of this software and associated documentation | |
+ * files (the "Software"), to deal in the Software without | |
+ * restriction, including without limitation the rights to use, copy, | |
+ * modify, merge, publish, distribute, sublicense, and/or sell copies | |
+ * of the Software, and to permit persons to whom the Software is | |
+ * furnished to do so, subject to the following conditions: | |
+ * | |
+ * The above copyright notice and this permission notice shall be | |
+ * included in all copies or substantial portions of the Software. | |
+ * | |
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
+ * SOFTWARE. | |
+ * | |
+ * Authors: | |
+ * Evan Nemerson <evan@coeus-group.com> | |
+ */ | |
+ | |
+#include <assert.h> | |
+#include <stdlib.h> | |
+#include <string.h> | |
+#include <strings.h> | |
+#include <errno.h> | |
+ | |
+#include <squash/squash.h> | |
+ | |
+#include "lzma-sdk/C/Ppmd7.h" | |
+ | |
+#define SQUASH_LZMA_SDK_PPMD7_DEFAULT_MEMORY (1 << 24) | |
+#define SQUASH_LZMA_SDK_PPMD7_DEFAULT_MAX_ORDER 6 | |
+ | |
+typedef struct SquashLzmaSdkPpmd7Options_s SquashLzmaSdkPpmd7Options; | |
+typedef struct SquashLzmaSdkPpmd7Writer_s SquashLzmaSdkPpmd7Writer; | |
+typedef struct SquashLzmaSdkPpmd7Reader_s SquashLzmaSdkPpmd7Reader; | |
+typedef struct SquashLzmaSdkPpmd7Stream_s SquashLzmaSdkPpmd7Stream; | |
+ | |
+struct SquashLzmaSdkPpmd7Options_s { | |
+ SquashOptions base_object; | |
+ | |
+ UInt32 memory; | |
+ unsigned max_order; | |
+}; | |
+ | |
+struct SquashLzmaSdkPpmd7Writer_s { | |
+ IByteOut parent; | |
+ SquashLzmaSdkPpmd7Stream* stream; | |
+}; | |
+ | |
+struct SquashLzmaSdkPpmd7Reader_s { | |
+ IByteIn parent; | |
+ SquashLzmaSdkPpmd7Stream* stream; | |
+}; | |
+ | |
+struct SquashLzmaSdkPpmd7Stream_s { | |
+ SquashStream base_object; | |
+ | |
+ uint8_t* buffer; | |
+ size_t buffer_size; | |
+ size_t buffer_length; | |
+ off_t buffer_pos; | |
+ | |
+ union { | |
+ SquashLzmaSdkPpmd7Writer writer; | |
+ SquashLzmaSdkPpmd7Reader reader; | |
+ } io; | |
+ | |
+ CPpmd7 ctx; | |
+ union { | |
+ CPpmd7z_RangeEnc encoder; | |
+ CPpmd7z_RangeDec decoder; | |
+ } coder; | |
+}; | |
+ | |
+SquashStatus squash_plugin_init_codec (SquashCodec* codec, | |
+ SquashCodecFuncs* funcs); | |
+ | |
+static void squash_lzma_sdk_ppmd7_options_init (SquashLzmaSdkPpmd7Options* options, | |
+ SquashCodec* codec, | |
+ SquashDestroyNotify destroy_notify); | |
+static SquashLzmaSdkPpmd7Options* squash_lzma_sdk_ppmd7_options_new (SquashCodec* codec); | |
+static void squash_lzma_sdk_ppmd7_options_destroy (void* options); | |
+static void squash_lzma_sdk_ppmd7_options_free (void* options); | |
+ | |
+static void squash_lzma_sdk_ppmd7_stream_init (SquashLzmaSdkPpmd7Stream* stream, | |
+ SquashCodec* codec, | |
+ SquashStreamType stream_type, | |
+ SquashLzmaSdkPpmd7Options* options, | |
+ SquashDestroyNotify destroy_notify); | |
+static SquashLzmaSdkPpmd7Stream* squash_lzma_sdk_ppmd7_stream_new (SquashCodec* codec, | |
+ SquashStreamType stream_type, | |
+ SquashLzmaSdkPpmd7Options* options); | |
+static void squash_lzma_sdk_ppmd7_stream_destroy (void* stream); | |
+static void squash_lzma_sdk_ppmd7_stream_free (void* stream); | |
+static SquashStream* squash_lzma_sdk_ppmd7_create_stream (SquashCodec* codec, | |
+ SquashStreamType stream_type, | |
+ SquashOptions* options); | |
+ | |
+static void* squash_lzma_sdk_malloc (void* p, size_t size); | |
+static void squash_lzma_sdk_free (void* p, void* address); | |
+static void squash_lzma_sdk_ppmd7_writer_write (void* p, Byte b); | |
+static Byte squash_lzma_sdk_ppmd7_reader_read (void* p); | |
+ | |
+ISzAlloc squash_lzma_sdk_system_memfuncs = { | |
+ squash_lzma_sdk_malloc, | |
+ squash_lzma_sdk_free | |
+}; | |
+ | |
+static void* | |
+squash_lzma_sdk_malloc (void* p, size_t size) { | |
+ return malloc (size); | |
+} | |
+ | |
+static void | |
+squash_lzma_sdk_free (void* p, void* address) { | |
+ free (address); | |
+} | |
+ | |
+static void | |
+squash_lzma_sdk_ppmd7_writer_write (void* p, Byte b) { | |
+ SquashLzmaSdkPpmd7Stream* stream = ((SquashLzmaSdkPpmd7Writer*) p)->stream; | |
+ SquashStream* s = (SquashStream*) stream; | |
+ | |
+ if ( stream->buffer_length == 0 && s->avail_out > 0 ) { | |
+ s->next_out[0] = b; | |
+ s->next_out++; | |
+ s->avail_out--; | |
+ } else { | |
+ if ( stream->buffer_size == 0 ) { | |
+ stream->buffer_size = 0xffff; | |
+ stream->buffer = (uint8_t*) malloc (stream->buffer_size); | |
+ } else if ( stream->buffer_length + stream->buffer_pos == stream->buffer_size ) { | |
+ stream->buffer_size <<= 1; | |
+ stream->buffer = (uint8_t*) realloc (stream->buffer, stream->buffer_size); | |
+ } | |
+ | |
+ stream->buffer[stream->buffer_pos + stream->buffer_length++] = (uint8_t) b; | |
+ } | |
+} | |
+ | |
+static Byte | |
+squash_lzma_sdk_ppmd7_reader_read (void* p) { | |
+ SquashLzmaSdkPpmd7Stream* stream = ((SquashLzmaSdkPpmd7Writer*) p)->stream; | |
+ SquashStream* s = (SquashStream*) stream; | |
+ Byte res; | |
+ | |
+ assert (s->avail_in > 0); | |
+ | |
+ res = s->next_in[0]; | |
+ s->next_in++; | |
+ s->avail_in--; | |
+ | |
+ return res; | |
+} | |
+ | |
+static void | |
+squash_lzma_sdk_ppmd7_options_init (SquashLzmaSdkPpmd7Options* options, SquashCodec* codec, SquashDestroyNotify destroy_notify) { | |
+ assert (options != NULL); | |
+ | |
+ squash_options_init ((SquashOptions*) options, codec, destroy_notify); | |
+ | |
+ options->memory = SQUASH_LZMA_SDK_PPMD7_DEFAULT_MEMORY; | |
+ options->max_order = SQUASH_LZMA_SDK_PPMD7_DEFAULT_MAX_ORDER; | |
+} | |
+ | |
+static SquashLzmaSdkPpmd7Options* | |
+squash_lzma_sdk_ppmd7_options_new (SquashCodec* codec) { | |
+ SquashLzmaSdkPpmd7Options* options; | |
+ | |
+ options = (SquashLzmaSdkPpmd7Options*) malloc (sizeof (SquashLzmaSdkPpmd7Options)); | |
+ squash_lzma_sdk_ppmd7_options_init (options, codec, squash_lzma_sdk_ppmd7_options_free); | |
+ | |
+ return options; | |
+} | |
+ | |
+static void | |
+squash_lzma_sdk_ppmd7_options_destroy (void* options) { | |
+ squash_options_destroy ((SquashOptions*) options); | |
+} | |
+ | |
+static void | |
+squash_lzma_sdk_ppmd7_options_free (void* options) { | |
+ squash_lzma_sdk_ppmd7_options_destroy ((SquashLzmaSdkPpmd7Options*) options); | |
+ free (options); | |
+} | |
+ | |
+static SquashOptions* | |
+squash_lzma_sdk_ppmd7_create_options (SquashCodec* codec) { | |
+ return (SquashOptions*) squash_lzma_sdk_ppmd7_options_new (codec); | |
+} | |
+ | |
+static SquashStatus | |
+squash_lzma_sdk_ppmd7_parse_option (SquashOptions* options, const char* key, const char* value) { | |
+ SquashLzmaSdkPpmd7Options* opts = (SquashLzmaSdkPpmd7Options*) options; | |
+ char* endptr = NULL; | |
+ | |
+ assert (opts != NULL); | |
+ | |
+ if (strcasecmp (key, "memory") == 0) { | |
+ const long int memory = strtol (value, &endptr, 0); | |
+ if ( *endptr == '\0' && memory >= PPMD7_MIN_MEM_SIZE && memory <= PPMD7_MAX_MEM_SIZE ) { | |
+ opts->memory = (UInt32) memory; | |
+ } else { | |
+ return SQUASH_BAD_VALUE; | |
+ } | |
+ } else if (strcasecmp (key, "max-order") == 0) { | |
+ const long int max_order = strtol (value, &endptr, 0); | |
+ if ( *endptr == '\0' && max_order >= PPMD7_MIN_ORDER && max_order <= PPMD7_MAX_ORDER ) { | |
+ opts->max_order = (unsigned int) max_order; | |
+ } else { | |
+ return SQUASH_BAD_VALUE; | |
+ } | |
+ } else { | |
+ return SQUASH_BAD_PARAM; | |
+ } | |
+ | |
+ return SQUASH_OK; | |
+} | |
+ | |
+static void | |
+squash_lzma_sdk_ppmd7_stream_init (SquashLzmaSdkPpmd7Stream* stream, | |
+ SquashCodec* codec, | |
+ SquashStreamType stream_type, | |
+ SquashLzmaSdkPpmd7Options* options, | |
+ SquashDestroyNotify destroy_notify) { | |
+ squash_stream_init ((SquashStream*) stream, codec, stream_type, (SquashOptions*) options, destroy_notify); | |
+ | |
+ switch ( stream_type ) { | |
+ case SQUASH_STREAM_COMPRESS: | |
+ stream->io.writer.parent.Write = squash_lzma_sdk_ppmd7_writer_write; | |
+ stream->io.writer.stream = stream; | |
+ break; | |
+ case SQUASH_STREAM_DECOMPRESS: | |
+ stream->io.reader.parent.Read = squash_lzma_sdk_ppmd7_reader_read; | |
+ stream->io.reader.stream = stream; | |
+ break; | |
+ } | |
+ | |
+ Ppmd7_Construct (&(stream->ctx)); | |
+ | |
+ stream->buffer = NULL; | |
+ stream->buffer_size = 0; | |
+ stream->buffer_length = 0; | |
+ stream->buffer_pos = 0; | |
+} | |
+ | |
+static void | |
+squash_lzma_sdk_ppmd7_stream_destroy (void* s) { | |
+ SquashLzmaSdkPpmd7Stream* stream = (SquashLzmaSdkPpmd7Stream*) s; | |
+ | |
+ if (Ppmd7_WasAllocated (&(stream->ctx))) { | |
+ Ppmd7_Free (&(stream->ctx), &squash_lzma_sdk_system_memfuncs); | |
+ } | |
+ | |
+ if ( stream->buffer != NULL ) { | |
+ free (stream->buffer); | |
+ } | |
+ | |
+ squash_stream_destroy (stream); | |
+} | |
+ | |
+static void | |
+squash_lzma_sdk_ppmd7_stream_free (void* stream) { | |
+ squash_lzma_sdk_ppmd7_stream_destroy (stream); | |
+ free (stream); | |
+} | |
+ | |
+static SquashLzmaSdkPpmd7Stream* | |
+squash_lzma_sdk_ppmd7_stream_new (SquashCodec* codec, SquashStreamType stream_type, SquashLzmaSdkPpmd7Options* options) { | |
+ SquashLzmaSdkPpmd7Stream* stream; | |
+ | |
+ assert (codec != NULL); | |
+ assert (stream_type == SQUASH_STREAM_COMPRESS || stream_type == SQUASH_STREAM_DECOMPRESS); | |
+ | |
+ stream = (SquashLzmaSdkPpmd7Stream*) malloc (sizeof (SquashLzmaSdkPpmd7Stream)); | |
+ squash_lzma_sdk_ppmd7_stream_init (stream, codec, stream_type, options, squash_lzma_sdk_ppmd7_stream_free); | |
+ | |
+ return stream; | |
+} | |
+ | |
+static SquashStream* | |
+squash_lzma_sdk_ppmd7_create_stream (SquashCodec* codec, SquashStreamType stream_type, SquashOptions* options) { | |
+ return (SquashStream*) squash_lzma_sdk_ppmd7_stream_new (codec, stream_type, (SquashLzmaSdkPpmd7Options*) options); | |
+} | |
+ | |
+#ifndef MIN | |
+#define MIN(a,b) (a < b ? a : b) | |
+#endif | |
+ | |
+#include <sys/types.h> | |
+#include <signal.h> | |
+ | |
+static SquashStatus | |
+squash_lzma_sdk_ppmd7_process_stream (SquashStream* s) { | |
+ SquashLzmaSdkPpmd7Stream* stream = (SquashLzmaSdkPpmd7Stream*) s; | |
+ bool progress = false; | |
+ size_t copy_size; | |
+ | |
+ if ( !Ppmd7_WasAllocated (&(stream->ctx)) ) { | |
+ const UInt32 memory = (s->options == NULL) ? | |
+ SQUASH_LZMA_SDK_PPMD7_DEFAULT_MEMORY : | |
+ ((SquashLzmaSdkPpmd7Options*) s->options)->memory; | |
+ const unsigned max_order = (s->options == NULL) ? | |
+ SQUASH_LZMA_SDK_PPMD7_DEFAULT_MAX_ORDER : | |
+ ((SquashLzmaSdkPpmd7Options*) s->options)->max_order; | |
+ | |
+ if ( !Ppmd7_Alloc (&(stream->ctx), memory, &squash_lzma_sdk_system_memfuncs) ) { | |
+ return SQUASH_MEMORY; | |
+ } | |
+ | |
+ switch (s->stream_type) { | |
+ case SQUASH_STREAM_COMPRESS: | |
+ Ppmd7z_RangeEnc_Init (&(stream->coder.encoder)); | |
+ stream->coder.encoder.Stream = (IByteOut*) &(stream->io.writer); | |
+ break; | |
+ case SQUASH_STREAM_DECOMPRESS: | |
+ stream->coder.decoder.Stream = (IByteIn*) &(stream->io.reader); | |
+ Ppmd7z_RangeDec_Init (&(stream->coder.decoder)); | |
+ Ppmd7z_RangeDec_CreateVTable(&(stream->coder.decoder)); | |
+ break; | |
+ } | |
+ | |
+ Ppmd7_Init(&(stream->ctx), max_order); | |
+ } | |
+ | |
+ copy_size = MIN(s->avail_out, stream->buffer_length); | |
+ if ( copy_size > 0 ) { | |
+ memcpy (s->next_out, stream->buffer + stream->buffer_pos, copy_size); | |
+ s->next_out += copy_size; | |
+ s->avail_out -= copy_size; | |
+ stream->buffer_length -= copy_size; | |
+ stream->buffer_pos = (stream->buffer_length == 0) ? 0 : (stream->buffer_pos + copy_size); | |
+ | |
+ if ( s->avail_in == 0 && stream->buffer_length == 0 ) | |
+ return SQUASH_OK; | |
+ | |
+ progress = true; | |
+ } | |
+ | |
+ while ( s->avail_in > 0 && s->avail_out > 0 ) { | |
+ switch (s->stream_type) { | |
+ case SQUASH_STREAM_COMPRESS: | |
+ Ppmd7_EncodeSymbol (&(stream->ctx), &(stream->coder.encoder), s->next_in[0]); | |
+ s->next_in++; | |
+ s->avail_in--; | |
+ break; | |
+ case SQUASH_STREAM_DECOMPRESS: | |
+ s->next_out[0] = (uint8_t) Ppmd7_DecodeSymbol (&(stream->ctx), &(stream->coder.decoder.p)); | |
+ s->next_out++; | |
+ s->avail_out--; | |
+ break; | |
+ } | |
+ | |
+ progress = true; | |
+ } | |
+ | |
+ return (s->avail_in == 0) ? SQUASH_OK : (progress ? SQUASH_PROCESSING : SQUASH_OK); | |
+} | |
+ | |
+static SquashStatus | |
+squash_lzma_sdk_ppmd7_flush_stream (SquashStream* s) { | |
+ SquashLzmaSdkPpmd7Stream* stream = (SquashLzmaSdkPpmd7Stream*) s; | |
+ SquashStatus status = squash_lzma_sdk_ppmd7_process_stream (s); | |
+ | |
+ if ( s->stream_type == SQUASH_STREAM_DECOMPRESS || status != SQUASH_OK ) { | |
+ return status; | |
+ } | |
+ | |
+ Ppmd7z_RangeEnc_FlushData (&(stream->coder.encoder)); | |
+ | |
+ return squash_lzma_sdk_ppmd7_process_stream (s); | |
+} | |
+ | |
+static SquashStatus | |
+squash_lzma_sdk_ppmd7_finish_stream (SquashStream* stream) { | |
+ SquashStatus status = squash_lzma_sdk_ppmd7_process_stream (stream); | |
+ | |
+ if ( status != SQUASH_OK ) { | |
+ return status; | |
+ } | |
+ | |
+ return squash_lzma_sdk_ppmd7_flush_stream (stream); | |
+} | |
+ | |
+static size_t | |
+squash_lzma_sdk_ppmd7_get_max_compressed_size (SquashCodec* codec, size_t uncompressed_length) { | |
+ return | |
+ uncompressed_length + | |
+ 5 + | |
+ (uncompressed_length / 10) + | |
+ (((uncompressed_length % 10) == 0) ? 0 : 1); | |
+} | |
+ | |
+SquashStatus | |
+squash_plugin_init_codec (SquashCodec* codec, SquashCodecFuncs* funcs) { | |
+ const char* name = squash_codec_get_name (codec); | |
+ | |
+ if (strcasecmp ("ppmd7", name) == 0) { | |
+ funcs->create_options = squash_lzma_sdk_ppmd7_create_options; | |
+ funcs->parse_option = squash_lzma_sdk_ppmd7_parse_option; | |
+ funcs->create_stream = squash_lzma_sdk_ppmd7_create_stream; | |
+ funcs->process_stream = squash_lzma_sdk_ppmd7_process_stream; | |
+ funcs->flush_stream = squash_lzma_sdk_ppmd7_flush_stream; | |
+ funcs->finish_stream = squash_lzma_sdk_ppmd7_finish_stream; | |
+ funcs->get_max_compressed_size = squash_lzma_sdk_ppmd7_get_max_compressed_size; | |
+ } else { | |
+ return SQUASH_UNABLE_TO_LOAD; | |
+ } | |
+ | |
+ return SQUASH_OK; | |
+} | |
-- | |
1.8.3.1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment