summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-05-06 11:00:49 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-05-06 11:00:49 +0200
commitcbcf86dde27767682483985e42f7ca49e1d3a208 (patch)
tree6abb8eabcda6e6aa64184aa24fb8c501f7c841b9
parenta5f604469d5cde8cb654e209f1ec30bf8e44b51e (diff)
Add LZO compressor implementation
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--README2
-rw-r--r--configure.ac22
-rw-r--r--lib/Makemodule.am7
-rw-r--r--lib/comp/compressor.c3
-rw-r--r--lib/comp/internal.h2
-rw-r--r--lib/comp/lzo.c71
-rw-r--r--mkfs/Makemodule.am4
-rw-r--r--unpack/Makemodule.am4
8 files changed, 114 insertions, 1 deletions
diff --git a/README b/README
index 98f6353..a953acf 100644
--- a/README
+++ b/README
@@ -83,5 +83,5 @@ At the moment, the following things are still missing:
- hard links
- NFS export tables
- compressor options
- - compressors other than XZ and GZIP (i.e. lzo, lz4, zstd, *maybe* lzma1?)
+ - compressors other than XZ and GZIP (i.e. lz4, zstd, *maybe* lzma1?)
- support for extracting SquashFS < 4.0
diff --git a/configure.ac b/configure.ac
index 4cb29bd..422a113 100644
--- a/configure.ac
+++ b/configure.ac
@@ -61,13 +61,25 @@ AC_ARG_WITH([xz],
esac],
[AM_CONDITIONAL([WITH_XZ], [true])])
+AC_ARG_WITH([lzo],
+ [AS_HELP_STRING([--without-lzo],
+ [Build without lzo compression support])],
+ [case "${withval}" in
+ yes) AM_CONDITIONAL([WITH_LZO], [true]) ;;
+ no) AM_CONDITIONAL([WITH_LZO], [false]) ;;
+ *) AC_MSG_ERROR([bad value ${withval} for --without-lzo]) ;;
+ esac],
+ [AM_CONDITIONAL([WITH_LZO], [true])])
+
##### search for dependencies #####
need_zlib="no"
need_xz="no"
+need_lzo="no"
AM_COND_IF([WITH_GZIP], [need_zlib="yes"])
AM_COND_IF([WITH_XZ], [need_xz="yes"])
+AM_COND_IF([WITH_LZO], [need_lzo="yes"])
if test "x$need_zlib" = "xyes"; then
PKG_CHECK_MODULES(ZLIB, [zlib], [], [AC_MSG_ERROR([cannot find zlib])])
@@ -78,6 +90,16 @@ if test "x$need_xz" = "xyes"; then
[AC_MSG_ERROR([cannot find xz sdk])])
fi
+if test "x$need_lzo" = "xyes"; then
+ AC_ARG_VAR([LZO_CFLAGS], [C compiler flags for lzo])
+ AC_ARG_VAR([LZO_LIBS], [linker flags for lzo])
+ AC_CHECK_LIB([lzo2], [lzo1x_1_15_compress], [LZO_LIBS="-llzo2"],
+ [AC_CHECK_LIB([lzo],[lzo1x_1_15_compress],[LZO_LIBS="-llzo"],
+ [AC_MSG_ERROR([cannot find lzo library])]
+ )]
+ )
+fi
+
##### generate output #####
AC_CONFIG_HEADERS([config.h])
diff --git a/lib/Makemodule.am b/lib/Makemodule.am
index d174c99..aacec34 100644
--- a/lib/Makemodule.am
+++ b/lib/Makemodule.am
@@ -35,4 +35,11 @@ libcompress_a_CFLAGS += $(XZ_CFLAGS)
libcompress_a_CPPFLAGS += -DWITH_XZ
endif
+if WITH_LZO
+libcompress_a_SOURCES += lib/comp/lzo.c
+
+libcompress_a_CFLAGS += $(LZO_CFLAGS)
+libcompress_a_CPPFLAGS += -DWITH_LZO
+endif
+
noinst_LIBRARIES += libfstree.a libcompress.a libutil.a libsquashfs.a
diff --git a/lib/comp/compressor.c b/lib/comp/compressor.c
index 1ede111..42ebd8b 100644
--- a/lib/comp/compressor.c
+++ b/lib/comp/compressor.c
@@ -12,6 +12,9 @@ static compressor_fun_t compressors[SQFS_COMP_MAX + 1] = {
#ifdef WITH_XZ
[SQFS_COMP_XZ] = create_xz_compressor,
#endif
+#ifdef WITH_LZO
+ [SQFS_COMP_LZO] = create_lzo_compressor,
+#endif
};
bool compressor_exists(E_SQFS_COMPRESSOR id)
diff --git a/lib/comp/internal.h b/lib/comp/internal.h
index d1cf1f2..3b24af0 100644
--- a/lib/comp/internal.h
+++ b/lib/comp/internal.h
@@ -8,4 +8,6 @@ compressor_t *create_xz_compressor(bool compress, size_t block_size);
compressor_t *create_gzip_compressor(bool compress, size_t block_size);
+compressor_t *create_lzo_compressor(bool compress, size_t block_size);
+
#endif /* INTERNAL_H */
diff --git a/lib/comp/lzo.c b/lib/comp/lzo.c
new file mode 100644
index 0000000..30b14cb
--- /dev/null
+++ b/lib/comp/lzo.c
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <lzo/lzo1x.h>
+
+#include "internal.h"
+
+typedef struct {
+ compressor_t base;
+
+ uint8_t buffer[LZO1X_999_MEM_COMPRESS];
+} lzo_compressor_t;
+
+static ssize_t lzo_comp_block(compressor_t *base, const uint8_t *in,
+ size_t size, uint8_t *out, size_t outsize)
+{
+ lzo_compressor_t *lzo = (lzo_compressor_t *)base;
+ lzo_uint len = outsize;
+
+ if (lzo1x_999_compress(in, size, out, &len, lzo->buffer) != LZO_E_OK) {
+ fputs("lzo1x_999 failed. According to its "
+ "manual, this shouldn't happen!\n", stderr);
+ return -1;
+ }
+
+ if (len < size)
+ return len;
+
+ return 0;
+}
+
+static ssize_t lzo_uncomp_block(compressor_t *base, const uint8_t *in,
+ size_t size, uint8_t *out, size_t outsize)
+{
+ lzo_compressor_t *lzo = (lzo_compressor_t *)base;
+ lzo_uint len = outsize;
+ int ret;
+
+ ret = lzo1x_decompress_safe(in, size, out, &len, lzo->buffer);
+
+ if (ret != LZO_E_OK) {
+ fputs("lzo decompress: input data is corrupted\n", stderr);
+ return -1;
+ }
+
+ return len;
+}
+
+static void lzo_destroy(compressor_t *base)
+{
+ free(base);
+}
+
+compressor_t *create_lzo_compressor(bool compress, size_t block_size)
+{
+ lzo_compressor_t *lzo = calloc(1, sizeof(*lzo));
+ compressor_t *base = (compressor_t *)lzo;
+ (void)block_size;
+
+ if (lzo == NULL) {
+ perror("creating lzo compressor");
+ return NULL;
+ }
+
+ base->destroy = lzo_destroy;
+ base->do_block = compress ? lzo_comp_block : lzo_uncomp_block;
+ return base;
+}
diff --git a/mkfs/Makemodule.am b/mkfs/Makemodule.am
index 5af5ad5..35e937c 100644
--- a/mkfs/Makemodule.am
+++ b/mkfs/Makemodule.am
@@ -10,4 +10,8 @@ if WITH_GZIP
gensquashfs_LDADD += $(ZLIB_LIBS)
endif
+if WITH_LZO
+gensquashfs_LDADD += $(LZO_LIBS)
+endif
+
bin_PROGRAMS += gensquashfs
diff --git a/unpack/Makemodule.am b/unpack/Makemodule.am
index d47cb5e..c3e61aa 100644
--- a/unpack/Makemodule.am
+++ b/unpack/Makemodule.am
@@ -12,4 +12,8 @@ if WITH_GZIP
rdsquashfs_LDADD += $(ZLIB_LIBS)
endif
+if WITH_LZO
+rdsquashfs_LDADD += $(LZO_LIBS)
+endif
+
bin_PROGRAMS += rdsquashfs