[libgsf] GsfOutputGzip: add "deflate-level" to control compression
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgsf] GsfOutputGzip: add "deflate-level" to control compression
- Date: Fri, 18 Oct 2019 20:05:08 +0000 (UTC)
commit f64435e6db5ba5a555bd15194c62e9d07c1fb908
Author: Morten Welinder <terra gnome org>
Date: Fri Oct 18 16:04:19 2019 -0400
GsfOutputGzip: add "deflate-level" to control compression
This must be set before the first write in order to take effect.
ChangeLog | 6 ++++
NEWS | 1 +
gsf/gsf-output-gzip.c | 81 +++++++++++++++++++++++++++++++--------------------
3 files changed, 57 insertions(+), 31 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 4290099..28d8c7f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2019-10-18 Morten Welinder <terra gnome org>
+
+ * gsf/gsf-output-gzip.c (gsf_output_gzip_class_init): Add
+ "deflate-level" attribute to control compression. Must be set
+ before first write. Based on code from Allin Cottrell.
+
2019-10-16 Morten Welinder <terra gnome org>
* gsf/gsf-output-memory.c (gsf_output_memory_steal_bytes): New
diff --git a/NEWS b/NEWS
index 7c165ae..c822b27 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ libgsf 1.14.47
Allin Cottrell:
* GsfOutputMemory improvement.
+ * Teach GsfOutputGzip to control compression level.
--------------------------------------------------------------------------
libgsf 1.14.46
diff --git a/gsf/gsf-output-gzip.c b/gsf/gsf-output-gzip.c
index 3d7b05c..d132fa6 100644
--- a/gsf/gsf-output-gzip.c
+++ b/gsf/gsf-output-gzip.c
@@ -35,10 +35,12 @@ struct _GsfOutputGZip {
GsfOutput *sink; /* compressed data */
gboolean raw; /* No header and no trailer. */
+ gint deflate_level; /* zlib compression level */
z_stream stream;
uLong crc; /* crc32 of uncompressed data */
size_t isize;
+ gboolean setup;
guint8 *buf;
size_t buf_size;
@@ -51,7 +53,8 @@ typedef struct {
enum {
PROP_0,
PROP_RAW,
- PROP_SINK
+ PROP_SINK,
+ PROP_DEFLATE_LEVEL
};
@@ -63,7 +66,7 @@ init_gzip (GsfOutputGZip *gzip)
{
int ret;
- ret = deflateInit2 (&gzip->stream, Z_DEFAULT_COMPRESSION,
+ ret = deflateInit2 (&gzip->stream, gzip->deflate_level,
Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL,
Z_DEFAULT_STRATEGY);
if (ret != Z_OK)
@@ -104,6 +107,24 @@ gzip_output_header (GsfOutputGZip *gzip)
return ret;
}
+static void
+gsf_output_gzip_setup (GsfOutputGZip *gzip)
+{
+ if (gzip->setup)
+ return;
+
+ if (!init_gzip (gzip))
+ gsf_output_set_error (GSF_OUTPUT (gzip),
+ 0,
+ "Failed to initialize zlib structure");
+ else if (!gzip->raw && !gzip_output_header (gzip))
+ gsf_output_set_error (GSF_OUTPUT (gzip),
+ 0,
+ "Failed to write gzip header");
+ else
+ gzip->setup = TRUE;
+}
+
/**
* gsf_output_gzip_new:
* @sink: The underlying data source.
@@ -204,6 +225,9 @@ gsf_output_gzip_write (GsfOutput *output,
g_return_val_if_fail (data, FALSE);
+ // Write header, if needed
+ gsf_output_gzip_setup (gzip);
+
gzip->stream.next_in = (unsigned char *) data;
gzip->stream.avail_in = num_bytes;
@@ -246,8 +270,12 @@ gsf_output_gzip_seek (G_GNUC_UNUSED GsfOutput *output,
static gboolean
gsf_output_gzip_close (GsfOutput *output)
{
+ GsfOutputGZip *gzip = GSF_OUTPUT_GZIP (output);
+
+ // Just in case nothing was ever written
+ gsf_output_gzip_setup (gzip);
+
if (!gsf_output_error (output)) {
- GsfOutputGZip *gzip = GSF_OUTPUT_GZIP (output);
if (!gzip_flush (gzip))
return FALSE;
@@ -279,8 +307,10 @@ gsf_output_gzip_init (GObject *obj)
gzip->stream.avail_in = gzip->stream.avail_out = 0;
gzip->crc = crc32 (0L, Z_NULL, 0);
gzip->isize = 0;
+ gzip->setup = FALSE;
gzip->buf = NULL;
gzip->buf_size = 0;
+ gzip->deflate_level = Z_DEFAULT_COMPRESSION;
}
static void
@@ -298,6 +328,9 @@ gsf_output_gzip_get_property (GObject *object,
case PROP_SINK:
g_value_set_object (value, gzip->sink);
break;
+ case PROP_DEFLATE_LEVEL:
+ g_value_set_int (value, gzip->deflate_level);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -329,45 +362,20 @@ gsf_output_gzip_set_property (GObject *object,
case PROP_SINK:
gsf_output_gzip_set_sink (gzip, g_value_get_object (value));
break;
+ case PROP_DEFLATE_LEVEL:
+ gzip->deflate_level = g_value_get_int (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
-static GObject*
-gsf_output_gzip_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_params)
-{
- GsfOutputGZip *gzip;
-
- gzip = (GsfOutputGZip *)(parent_class->constructor (type,
- n_construct_properties,
- construct_params));
-
- if (!gzip->sink)
- gsf_output_set_error (GSF_OUTPUT (gzip),
- 0,
- "NULL sink");
- else if (!init_gzip (gzip))
- gsf_output_set_error (GSF_OUTPUT (gzip),
- 0,
- "Failed to initialize zlib structure");
- else if (!gzip->raw && !gzip_output_header (gzip))
- gsf_output_set_error (GSF_OUTPUT (gzip),
- 0,
- "Failed to write gzip header");
-
- return (GObject *)gzip;
-}
-
static void
gsf_output_gzip_class_init (GObjectClass *gobject_class)
{
GsfOutputClass *output_class = GSF_OUTPUT_CLASS (gobject_class);
- gobject_class->constructor = gsf_output_gzip_constructor;
gobject_class->finalize = gsf_output_gzip_finalize;
gobject_class->set_property = gsf_output_gzip_set_property;
gobject_class->get_property = gsf_output_gzip_get_property;
@@ -393,6 +401,17 @@ gsf_output_gzip_class_init (GObjectClass *gobject_class)
GSF_PARAM_STATIC |
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property
+ (gobject_class,
+ PROP_DEFLATE_LEVEL,
+ g_param_spec_int ("deflate-level",
+ _("Deflate Level"),
+ _("The level of deflate compression used, zero meaning none "
+ "and -1 meaning the zlib default"),
+ -1, 9,
+ Z_DEFAULT_COMPRESSION,
+ GSF_PARAM_STATIC |
+ G_PARAM_READWRITE));
parent_class = g_type_class_peek_parent (gobject_class);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]