summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/szlibe.c')
-rw-r--r--base/szlibe.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/base/szlibe.c b/base/szlibe.c
new file mode 100644
index 00000000..4073dfc9
--- /dev/null
+++ b/base/szlibe.c
@@ -0,0 +1,96 @@
+/* Copyright (C) 2001-2019 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
+ CA 94945, U.S.A., +1(415)492-9861, for further information.
+*/
+
+
+/* zlib encoding (compression) filter stream */
+#include "std.h"
+#include "strimpl.h"
+#include "szlibxx.h"
+
+/* Initialize the filter. */
+static int
+s_zlibE_init(stream_state * st)
+{
+ stream_zlib_state *const ss = (stream_zlib_state *)st;
+ int code = s_zlib_alloc_dynamic_state(ss);
+
+ if (code < 0)
+ return ERRC; /****** WRONG ******/
+ if (deflateInit2(&ss->dynamic->zstate, ss->level, ss->method,
+ (ss->no_wrapper ? -ss->windowBits : ss->windowBits),
+ ss->memLevel, ss->strategy) != Z_OK)
+ return ERRC; /****** WRONG ******/
+ return 0;
+}
+
+/* Reinitialize the filter. */
+static int
+s_zlibE_reset(stream_state * st)
+{
+ stream_zlib_state *const ss = (stream_zlib_state *)st;
+
+ if (deflateReset(&ss->dynamic->zstate) != Z_OK)
+ return ERRC; /****** WRONG ******/
+ return 0;
+}
+
+/* Process a buffer */
+static int
+s_zlibE_process(stream_state * st, stream_cursor_read * pr,
+ stream_cursor_write * pw, bool last)
+{
+ stream_zlib_state *const ss = (stream_zlib_state *)st;
+ z_stream *zs = &ss->dynamic->zstate;
+ const byte *p = pr->ptr;
+ int status;
+
+ /* Detect no input or full output so that we don't get */
+ /* a Z_BUF_ERROR return. */
+ if (pw->ptr == pw->limit)
+ return 1;
+ if (p == pr->limit && !last)
+ return 0;
+ zs->next_in = (Bytef *)p + 1;
+ zs->avail_in = pr->limit - p;
+ zs->next_out = pw->ptr + 1;
+ zs->avail_out = pw->limit - pw->ptr;
+ status = deflate(zs, (last ? Z_FINISH : Z_NO_FLUSH));
+ pr->ptr = zs->next_in - 1;
+ pw->ptr = zs->next_out - 1;
+ switch (status) {
+ case Z_OK:
+ return (pw->ptr == pw->limit ? 1 : pr->ptr > p && !last ? 0 : 1);
+ case Z_STREAM_END:
+ return (last && pr->ptr == pr->limit ? 0 : ERRC);
+ default:
+ return ERRC;
+ }
+}
+
+/* Release the stream */
+static void
+s_zlibE_release(stream_state * st)
+{
+ stream_zlib_state *const ss = (stream_zlib_state *)st;
+
+ deflateEnd(&ss->dynamic->zstate);
+ s_zlib_free_dynamic_state(ss);
+}
+
+/* Stream template */
+const stream_template s_zlibE_template = {
+ &st_zlib_state, s_zlibE_init, s_zlibE_process, 1, 1, s_zlibE_release,
+ s_zlib_set_defaults, s_zlibE_reset
+};