Corrected (maybe) an error in the old Xt code that must have been
[xcircuit.git] / flate.c
blobc94eed3200b0ab1fca3759557329b0346bcc5d20
1 /*
2 * flate.c
4 * Copyright (c) Sergei Gerasenko 2003-2004.
6 * This defines the prototypes of the functions used for compressing
7 * and decompressing PDF streams. All of them utilize the zlib library
8 * and in fact the functions themselves are slightly modified versions
9 * of those included in an example file that came with the library. Kudos
10 * to the authors of zlib and everybody else involved in its development.
12 * This file was taken from the SourceForge project "acroformtool". Files
13 * "compression.c" and "compression.h" have been merged and modified as
14 * needed to facilitate compilation in xcircuit. Thanks once again to the
15 * open source community.
18 #ifdef HAVE_LIBZ
20 #include <stdio.h>
21 #include <zlib.h>
22 #include <string.h>
23 #include <stdlib.h>
25 #include <X11/Intrinsic.h>
26 #include <X11/StringDefs.h>
28 #ifdef TCL_WRAPPER
29 #include <tk.h>
30 #else
31 #include "Xw/Xw.h"
32 #endif
34 #include "xcircuit.h"
35 #include "prototypes.h" /* (jdk) */
38 * Substitute for original macro CHECK_ERROR
39 * Return 1 on error, 0 on success
42 int check_error(int err, char *prompt, char *msg) {
43 if (err != Z_OK) {
44 Fprintf(stderr, "%s error: %d", prompt, err);
45 if (msg) Fprintf(stderr, "(%s)", msg);
46 Fprintf(stderr, "\n");
47 return 1;
49 return 0;
53 * deflate() with large buffers
56 u_long large_deflate (u_char *compr, u_long compr_len,
57 u_char *uncompr, u_long uncompr_len) {
59 z_stream c_stream; /* compression stream */
60 int err;
62 c_stream.zalloc = (alloc_func)0;
63 c_stream.zfree = (free_func)0;
64 c_stream.opaque = (voidpf)0;
66 err = deflateInit(&c_stream, Z_BEST_SPEED);
67 if (check_error(err, "deflateInit", c_stream.msg)) return 0;
69 c_stream.next_out = compr;
70 c_stream.avail_out = (u_int)compr_len;
72 c_stream.next_in = uncompr;
73 c_stream.avail_in = (u_int)uncompr_len;
74 err = deflate(&c_stream, Z_NO_FLUSH);
75 if (check_error(err, "deflate", c_stream.msg)) return 0;
76 if (c_stream.avail_in != 0) {
77 Fprintf(stderr, "deflate not greedy");
80 err = deflate(&c_stream, Z_FINISH);
81 if (err != Z_STREAM_END) {
82 Fprintf(stderr, "deflate should report Z_STREAM_END");
84 err = deflateEnd(&c_stream);
85 if (check_error(err, "deflateEnd", c_stream.msg)) return 0;
87 /* Fprintf(stdout, "large_deflate(): OK\n"); */
89 return c_stream.total_out;
92 /*
93 * inflate() with large buffers
96 u_long large_inflate(u_char *compr, u_long compr_len,
97 u_char **uncompr, u_long uncompr_len) {
99 char *new_out_start;
100 int err;
101 z_stream d_stream; /* decompression stream */
103 d_stream.zalloc = (alloc_func)0;
104 d_stream.zfree = (free_func)0;
105 d_stream.opaque = (voidpf)0;
107 d_stream.next_in = compr;
108 d_stream.avail_in = (u_int)compr_len;
110 err = inflateInit(&d_stream);
111 if (check_error(err, "inflateInit", d_stream.msg)) return 0;
113 d_stream.next_out = *uncompr;
114 d_stream.avail_out = (u_int)uncompr_len;
116 for (;;) {
117 if (!d_stream.avail_out) {
118 /* Make more memory for the decompression buffer */
119 *uncompr = realloc(*uncompr, uncompr_len * 2);
121 /* Initialize new memory */
122 new_out_start = *uncompr + uncompr_len;
123 memset(new_out_start, 0, uncompr_len);
125 /* Point next_out to the next unused byte */
126 d_stream.next_out = new_out_start;
128 /* Update the size of the uncompressed buffer */
129 d_stream.avail_out = (u_int)uncompr_len;
132 err = inflate(&d_stream, Z_NO_FLUSH);
134 if (err == Z_STREAM_END) break;
136 if (check_error(err, "large inflate", d_stream.msg)) return 0;
139 err = inflateEnd(&d_stream);
140 if (check_error(err, "inflateEnd", d_stream.msg)) return 0;
142 /* Fprintf(stdout, "large_inflate(): OK\n"); */
144 return d_stream.total_out;
147 #endif /* HAVE_LIBZ */