Skip to content

Instantly share code, notes, and snippets.

@nemequ
Created August 22, 2013 20:25
Show Gist options
  • Save nemequ/6312324 to your computer and use it in GitHub Desktop.
Save nemequ/6312324 to your computer and use it in GitHub Desktop.
Squash gipfeli plugin (see https://github.com/quixdb/squash/issues/22)
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