Created
August 22, 2013 20:25
-
-
Save nemequ/6312324 to your computer and use it in GitHub Desktop.
Squash gipfeli plugin (see https://github.com/quixdb/squash/issues/22)
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 fb5360af92d5124174cb44266ce02fab2b16cfe8 Mon Sep 17 00:00:00 2001 | |
From: Evan Nemerson <evan@coeus-group.com> | |
Date: Thu, 22 Aug 2013 13:18:07 -0700 | |
Subject: [PATCH] Add gipfeli plugin. | |
https://github.com/quixdb/squash/issues/22 | |
--- | |
.gitmodules | 3 + | |
configure.ac | 3 +- | |
docs/index.md | 1 + | |
plugins/Makefile.am | 1 + | |
plugins/gipfeli/Makefile.am | 42 ++++++++++++ | |
plugins/gipfeli/gipfeli | 1 + | |
plugins/gipfeli/gipfeli.codecs | 1 + | |
plugins/gipfeli/gipfeli.m4 | 5 ++ | |
plugins/gipfeli/gipfeli.md | 16 +++++ | |
plugins/gipfeli/squash-gipfeli.cpp | 132 +++++++++++++++++++++++++++++++++++++ | |
10 files changed, 204 insertions(+), 1 deletion(-) | |
create mode 100644 plugins/gipfeli/Makefile.am | |
create mode 160000 plugins/gipfeli/gipfeli | |
create mode 100644 plugins/gipfeli/gipfeli.codecs | |
create mode 100644 plugins/gipfeli/gipfeli.m4 | |
create mode 100644 plugins/gipfeli/gipfeli.md | |
create mode 100644 plugins/gipfeli/squash-gipfeli.cpp | |
diff --git a/.gitmodules b/.gitmodules | |
index b60c204..dc789d9 100644 | |
--- a/.gitmodules | |
+++ b/.gitmodules | |
@@ -7,3 +7,6 @@ | |
[submodule "plugins/lzf/liblzf"] | |
path = plugins/lzf/liblzf | |
url = https://github.com/nemequ/liblzf.git | |
+[submodule "plugins/gipfeli/gipfeli"] | |
+ path = plugins/gipfeli/gipfeli | |
+ url = https://code.google.com/p/gipfeli/ | |
diff --git a/configure.ac b/configure.ac | |
index 92f1723..6d90d1e 100644 | |
--- a/configure.ac | |
+++ b/configure.ac | |
@@ -178,7 +178,7 @@ AC_SUBST(PLUGIN_LIBTOOL_FLAGS) | |
SQUASH_PLUGINS="" | |
SQUASH_PLUGINS_ENABLED="" | |
-m4_foreach([plugin],[bzip2, fastlz, lz4, lzma, lzf, lzo, quicklz, sharc, snappy, zlib, zpaq], [ | |
+m4_foreach([plugin],[bzip2, fastlz, gipfeli, lz4, lzma, lzf, lzo, quicklz, sharc, snappy, zlib, zpaq], [ | |
m4_include(plugins/plugin/plugin[.m4]) | |
SQUASH_PLUGINS="${SQUASH_PLUGINS} plugin" | |
]) | |
@@ -241,6 +241,7 @@ AC_CONFIG_FILES([Makefile | |
plugins/Makefile | |
plugins/bzip2/Makefile | |
plugins/fastlz/Makefile | |
+ plugins/gipfeli/Makefile | |
plugins/lz4/Makefile | |
plugins/lzma/Makefile | |
plugins/lzf/Makefile | |
diff --git a/docs/index.md b/docs/index.md | |
index dbbf952..2c06d25 100644 | |
--- a/docs/index.md | |
+++ b/docs/index.md | |
@@ -34,6 +34,7 @@ Squash currently contains plugins for the following libraries: | |
- [bzip2](@ref md_bzip2) | |
- [FastLZ](@ref md_fastlz) | |
+- [Gipfeli](@ref md_gipfeli) | |
- [LZ4](@ref md_lz4) | |
- [liblzma](@ref md_lzma) | |
- [LZF](@ref md_lzf) | |
diff --git a/plugins/Makefile.am b/plugins/Makefile.am | |
index 77dc813..019c1a3 100644 | |
--- a/plugins/Makefile.am | |
+++ b/plugins/Makefile.am | |
@@ -1,6 +1,7 @@ | |
SUBDIRS = \ | |
bzip2 \ | |
fastlz \ | |
+ gipfeli \ | |
lz4 \ | |
lzma \ | |
lzf \ | |
diff --git a/plugins/gipfeli/Makefile.am b/plugins/gipfeli/Makefile.am | |
new file mode 100644 | |
index 0000000..10c5f4f | |
--- /dev/null | |
+++ b/plugins/gipfeli/Makefile.am | |
@@ -0,0 +1,42 @@ | |
+COMMON_CFLAGS = \ | |
+ -I$(top_srcdir) \ | |
+ -DSQUASH_IS_UNSTABLE \ | |
+ -DSQUASH_COMPILATION | |
+ | |
+COMMON_LIBS = $(top_builddir)/squash/libsquash@SQUASH_API_VERSION@.la | |
+ | |
+GIPFELI_FILES = \ | |
+ gipfeli/decompress.cc \ | |
+ gipfeli/entropy.cc \ | |
+ gipfeli/entropy_code_builder.cc \ | |
+ gipfeli/gipfeli.cc \ | |
+ gipfeli/lz77.cc | |
+ | |
+if ENABLE_GIPFELI | |
+ | |
+plugindir = $(libdir)/squash/@SQUASH_API_VERSION@/plugins/gipfeli | |
+plugin_DATA = gipfeli.codecs | |
+ | |
+plugin_LTLIBRARIES = \ | |
+ libsquash@SQUASH_API_VERSION@-plugin-gipfeli.la | |
+ | |
+endif | |
+ | |
+libsquash@SQUASH_API_VERSION@_plugin_gipfeli_la_CPPFLAGS = \ | |
+ -O3 \ | |
+ $(COMMON_CFLAGS) | |
+ | |
+libsquash@SQUASH_API_VERSION@_plugin_gipfeli_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) | |
+ | |
+libsquash@SQUASH_API_VERSION@_plugin_gipfeli_la_LIBADD = \ | |
+ $(COMMON_LIBS) | |
+ | |
+libsquash@SQUASH_API_VERSION@_plugin_gipfeli_la_SOURCES = \ | |
+ squash-gipfeli.cpp \ | |
+ $(GIPFELI_FILES) | |
+ | |
+EXTRA_DIST = \ | |
+ $(plugin_DATA) \ | |
+ gipfeli.md | |
+ | |
+-include $(top_srcdir)/git.mk | |
diff --git a/plugins/gipfeli/gipfeli b/plugins/gipfeli/gipfeli | |
new file mode 160000 | |
index 0000000..d792137 | |
--- /dev/null | |
+++ b/plugins/gipfeli/gipfeli | |
@@ -0,0 +1 @@ | |
+Subproject commit d79213707d4ba44786ee7169dcc031cd06619611 | |
diff --git a/plugins/gipfeli/gipfeli.codecs b/plugins/gipfeli/gipfeli.codecs | |
new file mode 100644 | |
index 0000000..6fe320e | |
--- /dev/null | |
+++ b/plugins/gipfeli/gipfeli.codecs | |
@@ -0,0 +1 @@ | |
+[gipfeli] | |
diff --git a/plugins/gipfeli/gipfeli.m4 b/plugins/gipfeli/gipfeli.m4 | |
new file mode 100644 | |
index 0000000..019bc82 | |
--- /dev/null | |
+++ b/plugins/gipfeli/gipfeli.m4 | |
@@ -0,0 +1,5 @@ | |
+AC_ARG_ENABLE([gipfeli], | |
+ [AC_HELP_STRING([--enable-gipfeli=@<:@yes/no@:>@], [Enable gipfeli plugin @<:@default=yes@:>@])],, | |
+ [enable_gipfeli=yes]) | |
+ | |
+AM_CONDITIONAL([ENABLE_GIPFELI], test x$enable_gipfeli = "xyes") | |
diff --git a/plugins/gipfeli/gipfeli.md b/plugins/gipfeli/gipfeli.md | |
new file mode 100644 | |
index 0000000..6a08cb6 | |
--- /dev/null | |
+++ b/plugins/gipfeli/gipfeli.md | |
@@ -0,0 +1,16 @@ | |
+# gipfeli Plugin # | |
+ | |
+Gipfeli is a fast compression library. | |
+ | |
+For more information about Gipfeli, see https://code.google.com/p/gipfeli/ | |
+ | |
+## Codecs ## | |
+ | |
+- **gipfeli** — Raw Gipfeli data. | |
+ | |
+## License ## | |
+ | |
+The gipfeli plugin is licensed under the [MIT | |
+License](http://opensource.org/licenses/MIT), and Gipfeli is licensed | |
+under the [Apache 2.0 | |
+License](http://www.apache.org/licenses/LICENSE-2.0). | |
diff --git a/plugins/gipfeli/squash-gipfeli.cpp b/plugins/gipfeli/squash-gipfeli.cpp | |
new file mode 100644 | |
index 0000000..8d2205a | |
--- /dev/null | |
+++ b/plugins/gipfeli/squash-gipfeli.cpp | |
@@ -0,0 +1,132 @@ | |
+/* 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 "gipfeli/gipfeli.h" | |
+ | |
+extern "C" SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecFuncs* funcs); | |
+ | |
+static size_t | |
+squash_gipfeli_get_max_compressed_size (SquashCodec* codec, size_t uncompressed_length) { | |
+ return gipfeli::Compressor::MaxCompressedSize (uncompressed_length); | |
+} | |
+ | |
+static size_t | |
+squash_gipfeli_get_uncompressed_size (SquashCodec* codec, const uint8_t* compressed, size_t compressed_length) { | |
+ size_t uncompressed_size = 0; | |
+ gipfeli::Status gipfeli_e = gipfeli::Uncompressor::GetUncompressedLength ((const char*) compressed, compressed_length, &uncompressed_size); | |
+ return (gipfeli_e == gipfeli::kOk) ? uncompressed_size : 0; | |
+} | |
+ | |
+static SquashStatus | |
+squash_gipfeli_status (gipfeli::Status status) { | |
+ SquashStatus res; | |
+ | |
+ switch (status) { | |
+ case gipfeli::kOk: | |
+ res = SQUASH_OK; | |
+ break; | |
+ default: | |
+ res = SQUASH_FAILED; | |
+ break; | |
+ } | |
+ | |
+ return res; | |
+} | |
+ | |
+static SquashStatus | |
+squash_gipfeli_decompress_buffer (SquashCodec* codec, | |
+ uint8_t* decompressed, size_t* decompressed_length, | |
+ const uint8_t* compressed, size_t compressed_length, | |
+ SquashOptions* options) { | |
+ gipfeli::Uncompressor uncompressor; | |
+ gipfeli::Status e; | |
+ std::string output; | |
+ | |
+ uncompressor.Init (); | |
+ | |
+ e = uncompressor.Uncompress ((const char*) compressed, compressed_length, &output); | |
+ if (e == gipfeli::kOk) { | |
+ if (output.length () <= *decompressed_length) { | |
+ *decompressed_length = output.length (); | |
+ memcpy (decompressed, output.c_str (), *decompressed_length); | |
+ | |
+ return SQUASH_OK; | |
+ } else { | |
+ return SQUASH_BUFFER_FULL; | |
+ } | |
+ } else { | |
+ return SQUASH_FAILED; | |
+ } | |
+} | |
+ | |
+static SquashStatus | |
+squash_gipfeli_compress_buffer (SquashCodec* codec, | |
+ uint8_t* compressed, size_t* compressed_length, | |
+ const uint8_t* uncompressed, size_t uncompressed_length, | |
+ SquashOptions* options) { | |
+ gipfeli::Compressor compressor; | |
+ gipfeli::Status e; | |
+ std::string output; | |
+ | |
+ compressor.Init (); | |
+ | |
+ e = compressor.Compress ((const char*) uncompressed, uncompressed_length, &output); | |
+ if (e == gipfeli::kOk) { | |
+ if (output.length () <= *compressed_length) { | |
+ *compressed_length = output.length (); | |
+ memcpy (compressed, output.c_str (), *compressed_length); | |
+ | |
+ return SQUASH_OK; | |
+ } else { | |
+ return SQUASH_BUFFER_FULL; | |
+ } | |
+ } else { | |
+ return SQUASH_FAILED; | |
+ } | |
+} | |
+ | |
+extern "C" SquashStatus | |
+squash_plugin_init_codec (SquashCodec* codec, SquashCodecFuncs* funcs) { | |
+ const char* name = squash_codec_get_name (codec); | |
+ | |
+ if (strcmp ("gipfeli", name) == 0) { | |
+ funcs->get_uncompressed_size = squash_gipfeli_get_uncompressed_size; | |
+ funcs->get_max_compressed_size = squash_gipfeli_get_max_compressed_size; | |
+ funcs->decompress_buffer = squash_gipfeli_decompress_buffer; | |
+ funcs->compress_buffer = squash_gipfeli_compress_buffer; | |
+ } 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