[gimp/metadata-browser] file-compressor: Add support for xz compressed files (bug #683159)
- From: Roman Joost <romanofski src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/metadata-browser] file-compressor: Add support for xz compressed files (bug #683159)
- Date: Thu, 13 Sep 2012 00:38:52 +0000 (UTC)
commit ccae2cf50090ae03eac1dab86c795cc1e6bb7676
Author: Mukund Sivaraman <muks banu com>
Date: Sun Sep 2 04:32:04 2012 +0530
file-compressor: Add support for xz compressed files (bug #683159)
This commit causes a compiler warning because string literals are of
type signed char, and we use a character out of the signed range in the
mimetype for xz. It can be fixed by changing the data type of the mime
string to (unsigned char *), and not using string literals, but that's
a bit too much for this commit.
configure.ac | 29 ++++-
plug-ins/file-compressor/Makefile.am | 4 +-
plug-ins/file-compressor/file-compressor.c | 207 ++++++++++++++++++++++++++++
3 files changed, 238 insertions(+), 2 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index b3d25d8..1ce04a3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -63,6 +63,7 @@ m4_define([libgudev_required_version], [167])
m4_define([exif_required_version], [0.6.15])
m4_define([lcms_required_version], [1.16])
m4_define([libpng_required_version], [1.2.37])
+m4_define([liblzma_required_version], [5.0.0])
AC_INIT([GIMP], [gimp_version],
@@ -1176,8 +1177,34 @@ fi
AM_CONDITIONAL(HAVE_BZIP2, test "x$have_libbzip2" = xyes)
AC_SUBST(BZIP2_LIBS)
+
+###################
+# Check for liblzma
+###################
+
+AC_ARG_WITH(liblzma, [ --without-liblzma build without LZMA support])
+
+have_liblzma=no
+if test "x$with_liblzma" != xno; then
+ have_liblzma=yes
+ PKG_CHECK_MODULES(LZMA, liblzma >= liblzma_required_version,
+ AC_DEFINE(HAVE_LIBLZMA, 1, [Define to 1 if liblzma is available]),
+ have_liblzma="no (liblzma not found or too old)")
+fi
+
+AC_SUBST(LZMA_CFLAGS)
+AC_SUBST(LZMA_LIBS)
+
+AM_CONDITIONAL(HAVE_LIBLZMA, test "x$have_liblzma" = xyes)
+
+
+#######################################################################
+# file-compressor is only built when all the compressor libraries are
+# available. We should revisit this at some point to make it build even
+# with fewer libraries.
+#######################################################################
have_compressor=no
-if test "x$have_zlib" = xyes && test "x$have_libbzip2" = xyes; then
+if test "x$have_zlib" = xyes && test "x$have_libbzip2" = xyes && test "x$have_liblzma" = xyes; then
have_compressor=yes
fi
diff --git a/plug-ins/file-compressor/Makefile.am b/plug-ins/file-compressor/Makefile.am
index e8263a4..710117b 100644
--- a/plug-ins/file-compressor/Makefile.am
+++ b/plug-ins/file-compressor/Makefile.am
@@ -23,6 +23,7 @@ INCLUDES = \
-I$(top_srcdir) \
$(GTK_CFLAGS) \
$(GEGL_CFLAGS) \
+ $(LZMA_CFLAGS) \
-I$(includedir)
LDADD = \
@@ -35,4 +36,5 @@ LDADD = \
$(RT_LIBS) \
$(INTLLIBS) \
$(Z_LIBS) \
- $(BZIP2_LIBS)
+ $(BZIP2_LIBS) \
+ $(LZMA_LIBS)
diff --git a/plug-ins/file-compressor/file-compressor.c b/plug-ins/file-compressor/file-compressor.c
index 8bfcc38..d5843c5 100644
--- a/plug-ins/file-compressor/file-compressor.c
+++ b/plug-ins/file-compressor/file-compressor.c
@@ -27,6 +27,9 @@
/* and, very loosely on hrz.c by */
/* Albert Cahalan <acahalan at cs.uml.edu> */
+/* LZMA compression code is based on code by Lasse Collin which was
+ * placed in the public-domain. */
+
/* This is reads and writes compressed image files for GIMP
*
* It should work with file names of the form
@@ -87,6 +90,7 @@
#include <zlib.h>
#include <bzlib.h>
+#include <lzma.h>
/* Author 1: Josh MacDonald (url.c) */
/* Author 2: Daniel Risacher (gz.c) */
@@ -159,6 +163,12 @@ bzip2_load (const char *infile,
static gboolean
bzip2_save (const char *infile,
const char *outfile);
+static gboolean
+xz_load (const char *infile,
+ const char *outfile);
+static gboolean
+xz_save (const char *infile,
+ const char *outfile);
static const Compressor compressors[] =
{
@@ -198,6 +208,25 @@ static const Compressor compressors[] =
"saves files compressed with bzip2",
"This procedure saves files in the bzip2 compressed format.",
bzip2_save
+ },
+
+ {
+ N_("xz archive"),
+ "application/x-xz",
+ "xcf.xz,xz,xcfxz",
+ "0,ustring,\xFD7zXZ\x00",
+ ".xcfxz",
+ ".xz",
+
+ "file-xz-load",
+ "loads files compressed with xz",
+ "This procedure loads files in the xz compressed format.",
+ xz_load,
+
+ "file-xz-save",
+ "saves files compressed with xz",
+ "This procedure saves files in the xz compressed format.",
+ xz_save
}
};
@@ -764,3 +793,181 @@ bzip2_save (const char *infile,
return ret;
}
+
+static gboolean
+xz_load (const char *infile,
+ const char *outfile)
+{
+ gboolean ret;
+ FILE *in;
+ FILE *out;
+ lzma_stream strm = LZMA_STREAM_INIT;
+ lzma_action action;
+ guint8 inbuf[BUFSIZ];
+ guint8 outbuf[BUFSIZ];
+ lzma_ret status;
+
+ ret = FALSE;
+ in = NULL;
+ out = NULL;
+
+ in = g_fopen (infile, "rb");
+ if (!in)
+ goto out;
+
+ out = g_fopen (outfile, "wb");
+ if (!out)
+ goto out;
+
+ if (lzma_stream_decoder (&strm, UINT64_MAX, 0) != LZMA_OK)
+ goto out;
+
+ strm.next_in = NULL;
+ strm.avail_in = 0;
+ strm.next_out = outbuf;
+ strm.avail_out = sizeof outbuf;
+
+ action = LZMA_RUN;
+ status = LZMA_OK;
+
+ while (status == LZMA_OK)
+ {
+ /* Fill the input buffer if it is empty. */
+ if ((strm.avail_in == 0) && (!feof(in)))
+ {
+ strm.next_in = inbuf;
+ strm.avail_in = fread (inbuf, 1, sizeof inbuf, in);
+
+ if (ferror (in))
+ goto out;
+
+ /* Once the end of the input file has been reached, we need to
+ tell lzma_code() that no more input will be coming and that
+ it should finish the encoding. */
+ if (feof (in))
+ action = LZMA_FINISH;
+ }
+
+ status = lzma_code (&strm, action);
+
+ if ((strm.avail_out == 0) || (status == LZMA_STREAM_END))
+ {
+ /* When lzma_code() has returned LZMA_STREAM_END, the output
+ buffer is likely to be only partially full. Calculate how
+ much new data there is to be written to the output file. */
+ size_t write_size = sizeof outbuf - strm.avail_out;
+
+ if (fwrite (outbuf, 1, write_size, out) != write_size)
+ goto out;
+
+ /* Reset next_out and avail_out. */
+ strm.next_out = outbuf;
+ strm.avail_out = sizeof outbuf;
+ }
+ }
+
+ if (status != LZMA_STREAM_END)
+ goto out;
+
+ lzma_end (&strm);
+ ret = TRUE;
+
+ out:
+ if (in)
+ fclose (in);
+
+ if (out)
+ fclose (out);
+
+ return ret;
+}
+
+static gboolean
+xz_save (const char *infile,
+ const char *outfile)
+{
+ gboolean ret;
+ FILE *in;
+ FILE *out;
+ lzma_stream strm = LZMA_STREAM_INIT;
+ lzma_action action;
+ guint8 inbuf[BUFSIZ];
+ guint8 outbuf[BUFSIZ];
+ lzma_ret status;
+
+ ret = FALSE;
+ in = NULL;
+ out = NULL;
+
+ in = g_fopen (infile, "rb");
+ if (!in)
+ goto out;
+
+ out = g_fopen (outfile, "wb");
+ if (!out)
+ goto out;
+
+ if (lzma_easy_encoder (&strm,
+ LZMA_PRESET_DEFAULT,
+ LZMA_CHECK_CRC64) != LZMA_OK)
+ goto out;
+
+ strm.next_in = NULL;
+ strm.avail_in = 0;
+ strm.next_out = outbuf;
+ strm.avail_out = sizeof outbuf;
+
+ action = LZMA_RUN;
+ status = LZMA_OK;
+
+ while (status == LZMA_OK)
+ {
+ /* Fill the input buffer if it is empty. */
+ if ((strm.avail_in == 0) && (!feof(in)))
+ {
+ strm.next_in = inbuf;
+ strm.avail_in = fread (inbuf, 1, sizeof inbuf, in);
+
+ if (ferror (in))
+ goto out;
+
+ /* Once the end of the input file has been reached, we need to
+ tell lzma_code() that no more input will be coming and that
+ it should finish the encoding. */
+ if (feof (in))
+ action = LZMA_FINISH;
+ }
+
+ status = lzma_code (&strm, action);
+
+ if ((strm.avail_out == 0) || (status == LZMA_STREAM_END))
+ {
+ /* When lzma_code() has returned LZMA_STREAM_END, the output
+ buffer is likely to be only partially full. Calculate how
+ much new data there is to be written to the output file. */
+ size_t write_size = sizeof outbuf - strm.avail_out;
+
+ if (fwrite (outbuf, 1, write_size, out) != write_size)
+ goto out;
+
+ /* Reset next_out and avail_out. */
+ strm.next_out = outbuf;
+ strm.avail_out = sizeof outbuf;
+ }
+ }
+
+ if (status != LZMA_STREAM_END)
+ goto out;
+
+ lzma_end (&strm);
+ ret = TRUE;
+
+ out:
+ if (in)
+ fclose (in);
+
+ if (out)
+ fclose (out);
+
+ return ret;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]