summaryrefslogtreecommitdiff
path: root/Build/source/libs/potrace/potrace-1.12/src/flate.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/potrace/potrace-1.12/src/flate.c')
-rw-r--r--Build/source/libs/potrace/potrace-1.12/src/flate.c380
1 files changed, 380 insertions, 0 deletions
diff --git a/Build/source/libs/potrace/potrace-1.12/src/flate.c b/Build/source/libs/potrace/potrace-1.12/src/flate.c
new file mode 100644
index 00000000000..9e1e7232dd7
--- /dev/null
+++ b/Build/source/libs/potrace/potrace-1.12/src/flate.c
@@ -0,0 +1,380 @@
+/* Copyright (C) 2001-2015 Peter Selinger.
+ This file is part of Potrace. It is free software and it is covered
+ by the GNU General Public License. See the file COPYING for details. */
+
+
+/* the PostScript compression module of Potrace. The basic interface
+ is through the *_xship function, which processes a byte array and
+ outputs it in compressed or verbatim form, depending on whether
+ filter is 1 or 0. To flush the output, simply call with the empty
+ string and filter=0. filter=2 is used to output encoded text but
+ without the PostScript header to turn on the encoding. Each
+ function has variants for shipping a single character, a
+ null-terminated string, or a byte array. */
+
+/* different compression algorithms are available. There is
+ dummy_xship, which is just the identity, and flate_xship, which
+ uses zlib compression. Also, lzw_xship provides LZW compression
+ from the file lzw.c/h. a85_xship provides a85-encoding without
+ compression. Each function returns the actual number of characters
+ written. */
+
+/* note: the functions provided here have global state and are not
+ reentrant */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#ifdef HAVE_ZLIB
+#include <zlib.h>
+#endif
+
+#include "flate.h"
+#include "lzw.h"
+
+#define OUTSIZE 1000
+
+static int a85init(FILE *f);
+static int a85finish(FILE *f);
+static int a85write(FILE *f, char *buf, int n);
+static int a85out(FILE *f, int n);
+static int a85spool(FILE *f, char c);
+
+/* ---------------------------------------------------------------------- */
+/* dummy interface: no encoding */
+
+int dummy_xship(FILE *f, int filter, char *s, int len) {
+ fwrite(s, 1, len, f);
+ return len;
+}
+
+/* ---------------------------------------------------------------------- */
+/* flate interface: zlib (=postscript level 3) compression and a85 */
+
+#ifdef HAVE_ZLIB
+
+int pdf_xship(FILE *f, int filter, char *s, int len) {
+ static int fstate = 0;
+ static z_stream c_stream;
+ char outbuf[OUTSIZE];
+ int err;
+ int n=0;
+
+ if (filter && !fstate) {
+ /* switch on filtering */
+ c_stream.zalloc = Z_NULL;
+ c_stream.zfree = Z_NULL;
+ c_stream.opaque = Z_NULL;
+ err = deflateInit(&c_stream, 9);
+ if (err != Z_OK) {
+ fprintf(stderr, "deflateInit: %s (%d)\n", c_stream.msg, err);
+ exit(1);
+ }
+ c_stream.avail_in = 0;
+ fstate = 1;
+ } else if (!filter && fstate) {
+ /* switch off filtering */
+ /* flush stream */
+ do {
+ c_stream.next_out = (Bytef*)outbuf;
+ c_stream.avail_out = OUTSIZE;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_OK && err != Z_STREAM_END) {
+ fprintf(stderr, "deflate: %s (%d)\n", c_stream.msg, err);
+ exit(1);
+ }
+ n += fwrite(outbuf, 1, OUTSIZE-c_stream.avail_out, f);
+ } while (err != Z_STREAM_END);
+
+ fstate = 0;
+ }
+ if (!fstate) {
+ fwrite(s, 1, len, f);
+ return n+len;
+ }
+
+ /* do the actual compression */
+ c_stream.next_in = (Bytef*) s;
+ c_stream.avail_in = len;
+
+ do {
+ c_stream.next_out = (Bytef*) outbuf;
+ c_stream.avail_out = OUTSIZE;
+
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ if (err != Z_OK) {
+ fprintf(stderr, "deflate: %s (%d)\n", c_stream.msg, err);
+ exit(1);
+ }
+ n += fwrite(outbuf, 1, OUTSIZE-c_stream.avail_out, f);
+ } while (!c_stream.avail_out);
+
+ return n;
+}
+
+/* ship len bytes from s using zlib compression. */
+int flate_xship(FILE *f, int filter, char *s, int len) {
+ static int fstate = 0;
+ static z_stream c_stream;
+ char outbuf[OUTSIZE];
+ int err;
+ int n=0;
+
+ if (filter && !fstate) {
+ /* switch on filtering */
+ if (filter == 1) {
+ n += fprintf(f, "currentfile /ASCII85Decode filter /FlateDecode filter cvx exec\n");
+ }
+ c_stream.zalloc = Z_NULL;
+ c_stream.zfree = Z_NULL;
+ c_stream.opaque = Z_NULL;
+ err = deflateInit(&c_stream, 9);
+ if (err != Z_OK) {
+ fprintf(stderr, "deflateInit: %s (%d)\n", c_stream.msg, err);
+ exit(1);
+ }
+ c_stream.avail_in = 0;
+ n += a85init(f);
+ fstate = 1;
+ } else if (!filter && fstate) {
+ /* switch off filtering */
+ /* flush stream */
+ do {
+ c_stream.next_out = (Bytef*)outbuf;
+ c_stream.avail_out = OUTSIZE;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_OK && err != Z_STREAM_END) {
+ fprintf(stderr, "deflate: %s (%d)\n", c_stream.msg, err);
+ exit(1);
+ }
+ n += a85write(f, outbuf, OUTSIZE-c_stream.avail_out);
+ } while (err != Z_STREAM_END);
+
+ n += a85finish(f);
+
+ fstate = 0;
+ }
+ if (!fstate) {
+ fwrite(s, 1, len, f);
+ return n+len;
+ }
+
+ /* do the actual compression */
+ c_stream.next_in = (Bytef*) s;
+ c_stream.avail_in = len;
+
+ do {
+ c_stream.next_out = (Bytef*) outbuf;
+ c_stream.avail_out = OUTSIZE;
+
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ if (err != Z_OK) {
+ fprintf(stderr, "deflate: %s (%d)\n", c_stream.msg, err);
+ exit(1);
+ }
+ n += a85write(f, outbuf, OUTSIZE-c_stream.avail_out);
+ } while (!c_stream.avail_out);
+
+ return n;
+}
+
+#else /* HAVE_ZLIB */
+
+int pdf_xship(FILE *f, int filter, char *s, int len) {
+ return dummy_xship(f, filter, s, len);
+}
+
+int flate_xship(FILE *f, int filter, char *s, int len) {
+ return dummy_xship(f, filter, s, len);
+}
+
+#endif /* HAVE_ZLIB */
+
+/* ---------------------------------------------------------------------- */
+/* lzw interface: LZW (=postscript level 2) compression with a85.
+ This relies on lzw.c/h to do the actual compression. */
+
+/* use Postscript level 2 compression. Ship len bytes from str. */
+int lzw_xship(FILE *f, int filter, char *str, int len) {
+ static int fstate = 0;
+ static lzw_stream_t *s = NULL;
+ char outbuf[OUTSIZE];
+ int err;
+ int n=0;
+
+ if (filter && !fstate) {
+ /* switch on filtering */
+ if (filter == 1) {
+ n += fprintf(f, "currentfile /ASCII85Decode filter /LZWDecode filter cvx exec\n");
+ }
+ s = lzw_init();
+ if (s == NULL) {
+ fprintf(stderr, "lzw_init: %s\n", strerror(errno));
+ exit(1);
+ }
+ n += a85init(f);
+ fstate = 1;
+ } else if (!filter && fstate) {
+ /* switch off filtering */
+ /* flush stream */
+ s->next_in = 0;
+ s->avail_in = 0;
+ do {
+ s->next_out = outbuf;
+ s->avail_out = OUTSIZE;
+
+ err = lzw_compress(s, LZW_EOD);
+ if (err) {
+ fprintf(stderr, "lzw_compress: %s\n", strerror(errno));
+ exit(1);
+ }
+ n += a85write(f, outbuf, OUTSIZE - s->avail_out);
+ } while (s->avail_out == 0);
+
+ n += a85finish(f);
+
+ lzw_free(s);
+ s = NULL;
+
+ fstate = 0;
+ }
+ if (!fstate) {
+ fwrite(str, 1, len, f);
+ return n+len;
+ }
+
+ /* do the actual compression */
+ s->next_in = str;
+ s->avail_in = len;
+
+ do {
+ s->next_out = outbuf;
+ s->avail_out = OUTSIZE;
+
+ err = lzw_compress(s, LZW_NORMAL);
+ if (err) {
+ fprintf(stderr, "lzw_compress: %s\n", strerror(errno));
+ exit(1);
+ }
+ n += a85write(f, outbuf, OUTSIZE - s->avail_out);
+ } while (s->avail_out == 0);
+
+ return n;
+}
+
+/* ---------------------------------------------------------------------- */
+/* a85 interface: a85 encoding without compression */
+
+/* ship len bytes from s using a85 encoding only. */
+int a85_xship(FILE *f, int filter, char *s, int len) {
+ static int fstate = 0;
+ int n=0;
+
+ if (filter && !fstate) {
+ /* switch on filtering */
+ if (filter == 1) {
+ n += fprintf(f, "currentfile /ASCII85Decode filter cvx exec\n");
+ }
+ n += a85init(f);
+ fstate = 1;
+ } else if (!filter && fstate) {
+ /* switch off filtering */
+ /* flush stream */
+ n += a85finish(f);
+ fstate = 0;
+ }
+ if (!fstate) {
+ fwrite(s, 1, len, f);
+ return n+len;
+ }
+
+ n += a85write(f, s, len);
+
+ return n;
+}
+
+/* ---------------------------------------------------------------------- */
+/* low-level a85 backend */
+
+static unsigned long a85buf[4];
+static int a85n;
+static int a85col;
+
+static int a85init(FILE *f) {
+ a85n = 0;
+ a85col = 0;
+ return 0;
+}
+
+static int a85finish(FILE *f) {
+ int r=0;
+
+ if (a85n) {
+ r+=a85out(f, a85n);
+ }
+ fputs("~>\n", f);
+ return r+2;
+}
+
+static int a85write(FILE *f, char *buf, int n) {
+ int i;
+ int r=0;
+
+ for (i=0; i<n; i++) {
+ a85buf[a85n] = (unsigned char)buf[i];
+ a85n++;
+
+ if (a85n == 4) {
+ r+=a85out(f, 4);
+ a85n = 0;
+ }
+ }
+ return r;
+}
+
+static int a85out(FILE *f, int n) {
+ char out[5];
+ unsigned long s;
+ int r=0;
+ int i;
+
+ for (i=n; i<4; i++) {
+ a85buf[i] = 0;
+ }
+
+ s = (a85buf[0]<<24) + (a85buf[1]<<16) + (a85buf[2]<<8) + (a85buf[3]<<0);
+
+ if (!s) {
+ r+=a85spool(f, 'z');
+ } else {
+ for (i=4; i>=0; i--) {
+ out[i] = s % 85;
+ s /= 85;
+ }
+ for (i=0; i<n+1; i++) {
+ r+=a85spool(f, out[i]+33);
+ }
+ }
+ return r;
+}
+
+static int a85spool(FILE *f, char c) {
+ fputc(c, f);
+
+ a85col++;
+ if (a85col>70) {
+ fputc('\n', f);
+ a85col=0;
+ return 2;
+ }
+
+ return 1;
+}