xref: /plan9/sys/src/cmd/gs/src/szlibe.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: szlibe.c,v 1.4 2002/02/21 22:24:54 giles Exp $ */
18 /* zlib encoding (compression) filter stream */
19 #include "std.h"
20 #include "gsmemory.h"
21 #include "gsmalloc.h"		/* for gs_memory_default */
22 #include "strimpl.h"
23 #include "szlibxx.h"
24 
25 /* Initialize the filter. */
26 private int
s_zlibE_init(stream_state * st)27 s_zlibE_init(stream_state * st)
28 {
29     stream_zlib_state *const ss = (stream_zlib_state *)st;
30     int code = s_zlib_alloc_dynamic_state(ss);
31 
32     if (code < 0)
33 	return ERRC;	/****** WRONG ******/
34     if (deflateInit2(&ss->dynamic->zstate, ss->level, ss->method,
35 		     (ss->no_wrapper ? -ss->windowBits : ss->windowBits),
36 		     ss->memLevel, ss->strategy) != Z_OK)
37 	return ERRC;	/****** WRONG ******/
38     return 0;
39 }
40 
41 /* Reinitialize the filter. */
42 private int
s_zlibE_reset(stream_state * st)43 s_zlibE_reset(stream_state * st)
44 {
45     stream_zlib_state *const ss = (stream_zlib_state *)st;
46 
47     if (deflateReset(&ss->dynamic->zstate) != Z_OK)
48 	return ERRC;	/****** WRONG ******/
49     return 0;
50 }
51 
52 /* Process a buffer */
53 private int
s_zlibE_process(stream_state * st,stream_cursor_read * pr,stream_cursor_write * pw,bool last)54 s_zlibE_process(stream_state * st, stream_cursor_read * pr,
55 		stream_cursor_write * pw, bool last)
56 {
57     stream_zlib_state *const ss = (stream_zlib_state *)st;
58     z_stream *zs = &ss->dynamic->zstate;
59     const byte *p = pr->ptr;
60     int status;
61 
62     /* Detect no input or full output so that we don't get */
63     /* a Z_BUF_ERROR return. */
64     if (pw->ptr == pw->limit)
65 	return 1;
66     if (p == pr->limit && !last)
67 	return 0;
68     zs->next_in = (Bytef *)p + 1;
69     zs->avail_in = pr->limit - p;
70     zs->next_out = pw->ptr + 1;
71     zs->avail_out = pw->limit - pw->ptr;
72     status = deflate(zs, (last ? Z_FINISH : Z_NO_FLUSH));
73     pr->ptr = zs->next_in - 1;
74     pw->ptr = zs->next_out - 1;
75     switch (status) {
76 	case Z_OK:
77 	    return (pw->ptr == pw->limit ? 1 : pr->ptr > p && !last ? 0 : 1);
78 	case Z_STREAM_END:
79 	    return (last && pr->ptr == pr->limit ? 0 : ERRC);
80 	default:
81 	    return ERRC;
82     }
83 }
84 
85 /* Release the stream */
86 private void
s_zlibE_release(stream_state * st)87 s_zlibE_release(stream_state * st)
88 {
89     stream_zlib_state *const ss = (stream_zlib_state *)st;
90 
91     deflateEnd(&ss->dynamic->zstate);
92     s_zlib_free_dynamic_state(ss);
93 }
94 
95 /* Stream template */
96 const stream_template s_zlibE_template = {
97     &st_zlib_state, s_zlibE_init, s_zlibE_process, 1, 1, s_zlibE_release,
98     s_zlib_set_defaults, s_zlibE_reset
99 };
100