Created
September 16, 2013 16:41
-
-
Save nemequ/6583163 to your computer and use it in GitHub Desktop.
Add wfLZ plugin. https://github.com/quixdb/squash/issues/56
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 ac471e882642849bdf94aa280d694b692c18780e Mon Sep 17 00:00:00 2001 | |
From: Evan Nemerson <evan@coeus-group.com> | |
Date: Mon, 16 Sep 2013 09:39:09 -0700 | |
Subject: [PATCH] Add wfLZ plugin. | |
https://github.com/quixdb/squash/issues/56 | |
Signed-off-by: Evan Nemerson <evan@coeus-group.com> | |
--- | |
.gitmodules | 3 + | |
configure.ac | 3 +- | |
docs/index.md | 1 + | |
plugins/Makefile.am | 1 + | |
plugins/wflz/Makefile.am | 37 +++++++++ | |
plugins/wflz/squash-wflz.c | 201 +++++++++++++++++++++++++++++++++++++++++++++ | |
plugins/wflz/wflz | 1 + | |
plugins/wflz/wflz.codecs | 1 + | |
plugins/wflz/wflz.m4 | 5 ++ | |
plugins/wflz/wflz.md | 23 ++++++ | |
10 files changed, 275 insertions(+), 1 deletion(-) | |
create mode 100644 plugins/wflz/Makefile.am | |
create mode 100644 plugins/wflz/squash-wflz.c | |
create mode 160000 plugins/wflz/wflz | |
create mode 100644 plugins/wflz/wflz.codecs | |
create mode 100644 plugins/wflz/wflz.m4 | |
create mode 100644 plugins/wflz/wflz.md | |
diff --git a/.gitmodules b/.gitmodules | |
index be8e0c4..9c2d813 100644 | |
--- a/.gitmodules | |
+++ b/.gitmodules | |
@@ -25,3 +25,6 @@ | |
[submodule "plugins/fastlz/fastlz"] | |
path = plugins/fastlz/fastlz | |
url = https://github.com/svn2github/fastlz.git | |
+[submodule "plugins/wflz/wflz"] | |
+ path = plugins/wflz/wflz | |
+ url = https://github.com/svn2github/wflz.git | |
diff --git a/configure.ac b/configure.ac | |
index 07bdbf5..059f0aa 100644 | |
--- a/configure.ac | |
+++ b/configure.ac | |
@@ -188,7 +188,7 @@ AC_SUBST(PLUGIN_LIBTOOL_FLAGS) | |
SQUASH_PLUGINS="" | |
SQUASH_PLUGINS_ENABLED="" | |
-m4_foreach([plugin],[blosc, bzip2, doboz, fastlz, lz4, lzg, lzma, lzmat, lzf, lzo, quicklz, sharc, snappy, zlib, zpaq], [ | |
+m4_foreach([plugin],[blosc, bzip2, doboz, fastlz, lz4, lzg, lzma, lzmat, lzf, lzo, quicklz, sharc, snappy, wflz, zlib, zpaq], [ | |
m4_include(plugins/plugin/plugin[.m4]) | |
SQUASH_PLUGINS="${SQUASH_PLUGINS} plugin" | |
]) | |
@@ -261,6 +261,7 @@ AC_CONFIG_FILES([Makefile | |
plugins/quicklz/Makefile | |
plugins/sharc/Makefile | |
plugins/snappy/Makefile | |
+ plugins/wflz/Makefile | |
plugins/zlib/Makefile | |
plugins/zpaq/Makefile | |
utils/Makefile | |
diff --git a/docs/index.md b/docs/index.md | |
index 737a1b0..886db76 100644 | |
--- a/docs/index.md | |
+++ b/docs/index.md | |
@@ -45,6 +45,7 @@ Squash currently contains plugins for the following libraries: | |
- [QuickLZ](@ref md_quicklz) | |
- [SHARC](@ref md_sharc) | |
- [Snappy](@ref md_snappy) | |
+- [wfLZ](@ref md_wflz) | |
- [zlib](@ref md_zlib) | |
- [ZPAQ](@ref md_zpaq) | |
diff --git a/plugins/Makefile.am b/plugins/Makefile.am | |
index efc6fe5..249a354 100644 | |
--- a/plugins/Makefile.am | |
+++ b/plugins/Makefile.am | |
@@ -12,6 +12,7 @@ SUBDIRS = \ | |
quicklz \ | |
sharc \ | |
snappy \ | |
+ wflz \ | |
zlib \ | |
zpaq | |
diff --git a/plugins/wflz/Makefile.am b/plugins/wflz/Makefile.am | |
new file mode 100644 | |
index 0000000..45e8478 | |
--- /dev/null | |
+++ b/plugins/wflz/Makefile.am | |
@@ -0,0 +1,37 @@ | |
+COMMON_CFLAGS = \ | |
+ -O3 \ | |
+ -I$(top_srcdir) \ | |
+ @WARN_CFLAGS@ \ | |
+ -Wno-strict-prototypes \ | |
+ -Wno-missing-prototypes \ | |
+ -DSQUASH_IS_UNSTABLE | |
+ | |
+WFLZ_FILES = \ | |
+ wflz/wfLZ.c | |
+ | |
+COMMON_LIBS = $(top_builddir)/squash/libsquash@SQUASH_API_VERSION@.la | |
+ | |
+plugindir = $(libdir)/squash/@SQUASH_API_VERSION@/plugins/wflz | |
+plugin_DATA = wflz.codecs | |
+ | |
+plugin_LTLIBRARIES = \ | |
+ libsquash@SQUASH_API_VERSION@-plugin-wflz.la | |
+ | |
+libsquash@SQUASH_API_VERSION@_plugin_wflz_la_CFLAGS = \ | |
+ $(COMMON_CFLAGS) | |
+ | |
+libsquash@SQUASH_API_VERSION@_plugin_wflz_la_LDFLAGS = \ | |
+ $(PLUGIN_LIBTOOL_FLAGS) | |
+ | |
+libsquash@SQUASH_API_VERSION@_plugin_wflz_la_LIBADD = \ | |
+ $(COMMON_LIBS) | |
+ | |
+libsquash@SQUASH_API_VERSION@_plugin_wflz_la_SOURCES = \ | |
+ $(WFLZ_FILES) \ | |
+ squash-wflz.c | |
+ | |
+EXTRA_DIST = \ | |
+ $(plugin_DATA) \ | |
+ wflz.md | |
+ | |
+include $(top_srcdir)/git.mk | |
diff --git a/plugins/wflz/squash-wflz.c b/plugins/wflz/squash-wflz.c | |
new file mode 100644 | |
index 0000000..9fe2a2b | |
--- /dev/null | |
+++ b/plugins/wflz/squash-wflz.c | |
@@ -0,0 +1,201 @@ | |
+/* 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 <squash/squash.h> | |
+ | |
+#include "wflz/wfLZ.h" | |
+ | |
+enum { | |
+ SQUASH_WFLZ_LITTLE_ENDIAN = 0x03020100ul, | |
+ SQUASH_WFLZ_BIG_ENDIAN = 0x00010203ul | |
+}; | |
+ | |
+static const union { | |
+ unsigned char bytes[4]; | |
+ uint32_t value; | |
+} squash_wflz_host_order = { { 0, 1, 2, 3 } }; | |
+ | |
+#define SQUASH_WFLZ_HOST_ORDER (squash_wflz_host_order.value) | |
+ | |
+typedef struct SquashWflzOptions_s { | |
+ SquashOptions base_object; | |
+ | |
+ int level; | |
+ uint32_t endianness; | |
+} SquashWflzOptions; | |
+ | |
+#define SQUASH_WFLZ_DEFAULT_LEVEL 2 | |
+#define SQUASH_WFLZ_DEFAULT_ENDIAN SQUASH_WFLZ_LITTLE_ENDIAN | |
+ | |
+SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecFuncs* funcs); | |
+ | |
+static void squash_wflz_options_init (SquashWflzOptions* options, SquashCodec* codec, SquashDestroyNotify destroy_notify); | |
+static SquashWflzOptions* squash_wflz_options_new (SquashCodec* codec); | |
+static void squash_wflz_options_destroy (void* options); | |
+static void squash_wflz_options_free (void* options); | |
+ | |
+static void | |
+squash_wflz_options_init (SquashWflzOptions* options, SquashCodec* codec, SquashDestroyNotify destroy_notify) { | |
+ assert (options != NULL); | |
+ | |
+ squash_options_init ((SquashOptions*) options, codec, destroy_notify); | |
+ | |
+ options->level = SQUASH_WFLZ_DEFAULT_LEVEL; | |
+ options->endianness = SQUASH_WFLZ_LITTLE_ENDIAN; | |
+} | |
+ | |
+static SquashWflzOptions* | |
+squash_wflz_options_new (SquashCodec* codec) { | |
+ SquashWflzOptions* options; | |
+ | |
+ options = (SquashWflzOptions*) malloc (sizeof (SquashWflzOptions)); | |
+ squash_wflz_options_init (options, codec, squash_wflz_options_free); | |
+ | |
+ return options; | |
+} | |
+ | |
+static void | |
+squash_wflz_options_destroy (void* options) { | |
+ squash_options_destroy ((SquashOptions*) options); | |
+} | |
+ | |
+static void | |
+squash_wflz_options_free (void* options) { | |
+ squash_wflz_options_destroy ((SquashWflzOptions*) options); | |
+ free (options); | |
+} | |
+ | |
+static SquashOptions* | |
+squash_wflz_create_options (SquashCodec* codec) { | |
+ return (SquashOptions*) squash_wflz_options_new (codec); | |
+} | |
+ | |
+static SquashStatus | |
+squash_wflz_parse_option (SquashOptions* options, const char* key, const char* value) { | |
+ SquashWflzOptions* opts = (SquashWflzOptions*) options; | |
+ char* endptr = NULL; | |
+ | |
+ assert (opts != NULL); | |
+ | |
+ if (strcasecmp (key, "level") == 0) { | |
+ const long level = strtol (value, &endptr, 0); | |
+ if ( *endptr == '\0' && level >= 1 && level <= 2 ) { | |
+ opts->level = (int) level; | |
+ } else { | |
+ return SQUASH_BAD_VALUE; | |
+ } | |
+ } else if (strcasecmp (key, "endianness") == 0) { | |
+ if (strcasecmp (value, "little") == 0) { | |
+ opts->endianness = SQUASH_WFLZ_LITTLE_ENDIAN; | |
+ } else if (strcasecmp (value, "big")) { | |
+ opts->endianness = SQUASH_WFLZ_BIG_ENDIAN; | |
+ } else { | |
+ return SQUASH_BAD_VALUE; | |
+ } | |
+ } else { | |
+ return SQUASH_BAD_PARAM; | |
+ } | |
+ | |
+ return SQUASH_OK; | |
+} | |
+ | |
+static size_t | |
+squash_wflz_get_max_compressed_size (SquashCodec* codec, size_t uncompressed_length) { | |
+ return (size_t) wfLZ_GetMaxCompressedSize ((uint32_t) uncompressed_length); | |
+} | |
+ | |
+static size_t | |
+squash_wflz_get_uncompressed_size (SquashCodec* codec, const uint8_t* compressed, size_t compressed_length) { | |
+ if (compressed_length < 12) | |
+ return 0; | |
+ | |
+ return (size_t) wfLZ_GetDecompressedSize (compressed); | |
+} | |
+ | |
+static SquashStatus | |
+squash_wflz_compress_buffer (SquashCodec* codec, | |
+ uint8_t* compressed, size_t* compressed_length, | |
+ const uint8_t* uncompressed, size_t uncompressed_length, | |
+ SquashOptions* options) { | |
+ const uint32_t swap = ((options == NULL) ? SQUASH_WFLZ_DEFAULT_ENDIAN : ((SquashWflzOptions*) options)->endianness) != SQUASH_WFLZ_HOST_ORDER; | |
+ const int level = (options == NULL) ? SQUASH_WFLZ_DEFAULT_LEVEL : ((SquashWflzOptions*) options)->level; | |
+ | |
+ if (*compressed_length < wfLZ_GetMaxCompressedSize ((uint32_t) uncompressed_length)) { | |
+ return SQUASH_BUFFER_FULL; | |
+ } | |
+ | |
+ uint8_t* work_mem = (uint8_t*) malloc (wfLZ_GetWorkMemSize ()); | |
+ | |
+ if (level == 1) { | |
+ *compressed_length = (size_t) wfLZ_CompressFast (uncompressed, (uint32_t) uncompressed_length, | |
+ compressed, work_mem, swap); | |
+ } else { | |
+ *compressed_length = (size_t) wfLZ_Compress (uncompressed, (uint32_t) uncompressed_length, | |
+ compressed, work_mem, swap); | |
+ } | |
+ | |
+ free (work_mem); | |
+ | |
+ return (*compressed_length > 0) ? SQUASH_OK : SQUASH_FAILED; | |
+} | |
+ | |
+static SquashStatus | |
+squash_wflz_decompress_buffer (SquashCodec* codec, | |
+ uint8_t* decompressed, size_t* decompressed_length, | |
+ const uint8_t* compressed, size_t compressed_length, | |
+ SquashOptions* options) { | |
+ uint32_t decompressed_size; | |
+ | |
+ if (compressed_length < 12 || (decompressed_size = wfLZ_GetDecompressedSize (compressed)) > *decompressed_length) { | |
+ return SQUASH_FAILED; | |
+ } | |
+ | |
+ wfLZ_Decompress (compressed, decompressed); | |
+ return SQUASH_OK; | |
+} | |
+ | |
+SquashStatus | |
+squash_plugin_init_codec (SquashCodec* codec, SquashCodecFuncs* funcs) { | |
+ const char* name = squash_codec_get_name (codec); | |
+ | |
+ if (strcmp ("wflz", name) == 0) { | |
+ funcs->create_options = squash_wflz_create_options; | |
+ funcs->parse_option = squash_wflz_parse_option; | |
+ funcs->get_uncompressed_size = squash_wflz_get_uncompressed_size; | |
+ funcs->get_max_compressed_size = squash_wflz_get_max_compressed_size; | |
+ funcs->decompress_buffer = squash_wflz_decompress_buffer; | |
+ funcs->compress_buffer = squash_wflz_compress_buffer; | |
+ } else { | |
+ return SQUASH_UNABLE_TO_LOAD; | |
+ } | |
+ | |
+ return SQUASH_OK; | |
+} | |
diff --git a/plugins/wflz/wflz b/plugins/wflz/wflz | |
new file mode 160000 | |
index 0000000..1e5e0ef | |
--- /dev/null | |
+++ b/plugins/wflz/wflz | |
@@ -0,0 +1 @@ | |
+Subproject commit 1e5e0ef46d1f4a4bb872e22502c08f9d6fb0e726 | |
diff --git a/plugins/wflz/wflz.codecs b/plugins/wflz/wflz.codecs | |
new file mode 100644 | |
index 0000000..e829f9e | |
--- /dev/null | |
+++ b/plugins/wflz/wflz.codecs | |
@@ -0,0 +1 @@ | |
+[wflz] | |
diff --git a/plugins/wflz/wflz.m4 b/plugins/wflz/wflz.m4 | |
new file mode 100644 | |
index 0000000..df9b2d9 | |
--- /dev/null | |
+++ b/plugins/wflz/wflz.m4 | |
@@ -0,0 +1,5 @@ | |
+AC_ARG_ENABLE([wflz], | |
+ [AC_HELP_STRING([--enable-wflz=@<:@yes/no@:>@], [Enable wflz plugin @<:@default=yes@:>@])],, | |
+ [enable_wflz=yes]) | |
+ | |
+AM_CONDITIONAL([ENABLE_WFLZ], test x$enable_wflz = "xyes") | |
diff --git a/plugins/wflz/wflz.md b/plugins/wflz/wflz.md | |
new file mode 100644 | |
index 0000000..9ccff7f | |
--- /dev/null | |
+++ b/plugins/wflz/wflz.md | |
@@ -0,0 +1,23 @@ | |
+# wflz Plugin # | |
+ | |
+For information about wfLZ, see https://code.google.com/p/wflz/ | |
+ | |
+## Codecs ## | |
+ | |
+- **wflz** — Raw wfLZ data. | |
+ | |
+## Options ## | |
+ | |
+- **level** (integer, 1-2, default 2) — compression level. Lower is | |
+ faster, higher has a better compression ratio. | |
+ | |
+### Compression Only ### | |
+ | |
+- **endianness** (enum, "little" or "big", default "little") — | |
+ Endianness of the compressed file. | |
+ | |
+## License ## | |
+ | |
+The wflz plugin is licensed under the [MIT | |
+License](http://opensource.org/licenses/MIT), and wfLZ is licensed | |
+under the [WTFPL](http://www.wtfpl.net/). | |
-- | |
1.8.3.1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment