summaryrefslogtreecommitdiff
path: root/src/cos_stream_filter.c
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2018-01-15 22:12:22 +0000
committerVincent Sanders <vince@kyllikki.org>2018-01-15 22:12:22 +0000
commita59a9fcbb5dd67f4368e88b9caa773b9c56811f9 (patch)
tree0e57e507c9ee61d9c4bf74cd27582c476625478a /src/cos_stream_filter.c
parentb668680da5aa0930820df70f1b182243a7a8cde4 (diff)
downloadlibnspdf-a59a9fcbb5dd67f4368e88b9caa773b9c56811f9.tar.gz
libnspdf-a59a9fcbb5dd67f4368e88b9caa773b9c56811f9.tar.bz2
support flateDecode stream filter
Diffstat (limited to 'src/cos_stream_filter.c')
-rw-r--r--src/cos_stream_filter.c91
1 files changed, 87 insertions, 4 deletions
diff --git a/src/cos_stream_filter.c b/src/cos_stream_filter.c
index 6f407de..0c08442 100644
--- a/src/cos_stream_filter.c
+++ b/src/cos_stream_filter.c
@@ -13,21 +13,104 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <zlib.h>
#include <nspdf/errors.h>
#include "cos_object.h"
#include "pdf_doc.h"
+static nspdferror
+cos_stream_inflate(struct nspdf_doc *doc, struct cos_stream **stream_out)
+{
+ int ret;
+ z_stream strm;
+ struct cos_stream *stream_in;
+ struct cos_stream *stream_res;
+
+ stream_in = *stream_out;
+
+ stream_res = calloc(1, sizeof(struct cos_stream));
+
+ //printf("inflating from %d bytes\n", stream_in->length);
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+
+ ret = inflateInit(&strm);
+ if (ret != Z_OK) {
+ return NSPDFERROR_NOTFOUND;
+ }
+
+ strm.next_in = (void *)stream_in->data;
+ strm.avail_in = stream_in->length;
+
+ do {
+ int64_t available; /* available buffer space for decompression */
+ available = stream_res->alloc - stream_res->length;
+
+ if (available < (strm.avail_in << 1)) {
+ uint8_t *newdata;
+ size_t newlength;
+
+ newlength = stream_res->alloc + (stream_in->length << 1);
+ newdata = realloc((void *)stream_res->data, newlength);
+ if (newdata == NULL) {
+ free((void *)stream_res->data);
+ free(stream_res);
+ inflateEnd(&strm);
+ return NSPDFERROR_NOMEM;
+ }
+
+ //printf("realloc %d\n", newlength);
+
+ stream_res->data = newdata;
+ stream_res->alloc = newlength;
+ available = stream_res->alloc - stream_res->length;
+ }
+
+ strm.avail_out = available;
+ strm.next_out = (void*)(stream_res->data + stream_res->length);
+ ret = inflate(&strm, Z_NO_FLUSH);
+ /** \todo check zlib return code */
+
+ stream_res->length += (available - strm.avail_out);
+
+ } while (ret != Z_STREAM_END);
+
+ //printf("allocated %d\n", stream_res->alloc);
+
+ //printf("length %d\n", stream_res->length);
+
+ inflateEnd(&strm);
+
+ if (stream_in->alloc != 0) {
+ free((void*)stream_in->data);
+ }
+ free(stream_in);
+
+ *stream_out = stream_res;
+
+ return NSPDFERROR_OK;
+}
+
nspdferror
nspdf__cos_stream_filter(struct nspdf_doc *doc,
const char *filter_name,
struct cos_stream **stream_out)
{
- struct cos_stream *stream_in;
+ nspdferror res;
- stream_in = *stream_out;
+ //printf("applying filter %s\n", filter_name);
- printf("applying filter %s\n", filter_name);
- return NSPDFERROR_OK;
+ if (strcmp(filter_name, "FlateDecode") == 0) {
+ res = cos_stream_inflate(doc, stream_out);
+ } else {
+ res = NSPDFERROR_NOTFOUND;
+ }
+
+ return res;
}