[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[pdf-devel] LZW filter re-implementation
From: |
Juan Pedro Bolivar Puente |
Subject: |
[pdf-devel] LZW filter re-implementation |
Date: |
Sun, 28 Jun 2009 01:31:27 +0200 |
User-agent: |
Mozilla-Thunderbird 2.0.0.19 (X11/20090103) |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi,
I attach a new patch trying to adapt the LZW filter implementation to
the new filter API.
Some comments:
1. The filter now works with any cache size. I tested with the submited
test cases (from the standard specification) and long playing with
pdf-filter :)
2. Because of the cache size stuff, those embarrassing weird goto's are
kept. Maybe we can consider allowing the filters specify a
"minimum-cache" parameter to avoid non-necessary code bloat and/or
efficiency tradeoffs?
3. I added the pdf-filter patch submitted by jemarch the other day.
4. I factored out the test cases sent by Brad Hards using fixtures to
allocate/deallocate the stream. This may cause an overhead in the
overall runing time as the fixture is setup/teareddown on every test
cases. I still think that it would be useful to factor-out other tests
to use this fixture and so avoid setup/dealloc boilerplate -I did not do
it in case their authors disagree.
5. I disabled the tokenizer utility, it seems that a header file was
forgotten in the last commit.
6. Many thanks to Brad Hards for his work in this task.
Enjoy :)
JP
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iEYEARECAAYFAkpGq88ACgkQchi8veCammch/ACgnWu88IA2zgJOnG58MdaAcM60
TgEAnAllNQRLslljhfNYfjThT8zTasn2
=REVR
-----END PGP SIGNATURE-----
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: address@hidden
# target_branch: http://bzr.savannah.gnu.org/r/pdf/libgnupdf/branches\
# /trunk/
# testament_sha1: 6260da11d5ebb802e1a33b95dd7ec3a00cf74f2d
# timestamp: 2009-06-28 01:20:01 +0200
# base_revision_id: address@hidden
#
# Begin patch
=== modified file 'AUTHORS'
--- AUTHORS 2009-06-24 19:25:52 +0000
+++ AUTHORS 2009-06-27 23:19:51 +0000
@@ -282,6 +282,7 @@
and changed utils/pdf-filter.c utils/pdf-filter.h
src/base/pdf-stm.c src/base/pdf-stm.h
src/base/pdf-stm-be.c src/base/pdf-stm-be.h
+ torture/unit/base/stm/pdf-stm-write.c
Karl Berry: changed doc/gnupdf.texi doc/gnupdf-utils.texi
doc/Makefile.am
=== modified file 'ChangeLog'
--- ChangeLog 2009-06-24 19:25:52 +0000
+++ ChangeLog 2009-06-27 23:19:51 +0000
@@ -1,3 +1,16 @@
+2009-06-28 Juan Pedro BolÃvar Puente <address@hidden>
+
+ * src/base/pdf-stm-f-lzw.c: port of LZW filter to new API
+ * src/base/pdf-stm-f-lzw.h: likewise
+ * src/base/pdf-stm-filter.c: likewise
+ * src/base/pdf-stm-filter.h: likewise
+ * src/Makefile.am: integrate pdf-stm-f-lzw.[c,h] back into build
+ system
+ * torture/unit/base/stm/pdf-stm-write.c: add test case from PDF
+ specification version 1.7.
+ * (Brad Hards contributed to this patch)
+ * util/pdf-filter.c: added LZW filter. (by Jose E. Marchesi)
+
2009-06-24 Jose E. Marchesi <address@hidden>
* doc/pdf-tokeniser.1: New file, generated from
@@ -14,6 +27,19 @@
* utils/pdf-tokeniser.c: Renamed from 'utils/toktest.c'.
+
+2009-06-24 Jose E. Marchesi <address@hidden>
+
+ * src/base/pdf-hash-helper.h: Added functions 'pdf_hash_add_bool'
+ and 'pdf_hash_get_bool'.
+
+ * src/base/pdf-hash-helper.c: Likewise.
+
+ * utils/pdf-filter.h: Added support for the LZW filters.
+
+ * utils/pdf-filter.c: Likewise.
+
+
2009-06-22 Brad Hards <address@hidden>
* src/base/pdf-text.c (pdf_text_dup): Protect against NULL arg.
=== modified file 'src/Makefile.am'
--- src/Makefile.am 2009-05-20 15:54:43 +0000
+++ src/Makefile.am 2009-06-27 23:19:51 +0000
@@ -46,7 +46,8 @@
base/pdf-stm-f-rl.h base/pdf-stm-f-rl.c \
base/pdf-stm-f-v2.h base/pdf-stm-f-v2.c \
base/pdf-stm-f-aesv2.h base/pdf-stm-f-aesv2.c \
- base/pdf-stm-f-md5.h base/pdf-stm-f-md5.c
+ base/pdf-stm-f-md5.h base/pdf-stm-f-md5.c \
+ base/pdf-stm-f-lzw.h base/pdf-stm-f-lzw.c
if ZLIB
STM_MODULE_SOURCES += base/pdf-stm-f-flate.c base/pdf-stm-f-flate.h
=== modified file 'src/base/pdf-hash-helper.c'
--- src/base/pdf-hash-helper.c 2009-01-27 20:59:40 +0000
+++ src/base/pdf-hash-helper.c 2009-06-27 23:19:51 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "09/01/27 21:37:10 jemarch"
+/* -*- mode: C -*- Time-stamp: "09/06/24 20:13:29 jemarch"
*
* File: pdf-hash-helper.c
* Date: Thu Jul 24 21:05:05 2008
@@ -97,6 +97,37 @@
}
pdf_status_t
+pdf_hash_add_bool (pdf_hash_t table, const char *key, const pdf_bool_t elt)
+{
+ pdf_bool_t *vbool;
+
+ vbool = pdf_alloc (sizeof(pdf_bool_t));
+ if (vbool == NULL)
+ {
+ return PDF_ERROR;
+ }
+
+ *vbool = elt;
+
+ return (pdf_hash_add (table, key, vbool, pdf_dealloc));
+}
+
+pdf_status_t
+pdf_hash_get_bool (pdf_hash_t table, const char *key, pdf_bool_t *elt)
+{
+ pdf_status_t ret;
+ pdf_bool_t *vbool;
+
+ ret = pdf_hash_get (table, key, (const void **) &vbool);
+ if (ret == PDF_OK)
+ {
+ *elt = *vbool;
+ }
+
+ return ret;
+}
+
+pdf_status_t
pdf_hash_add_size (pdf_hash_t table, const char *key, const pdf_size_t elt)
{
pdf_size_t *size;
=== modified file 'src/base/pdf-hash-helper.h'
--- src/base/pdf-hash-helper.h 2008-12-28 01:13:47 +0000
+++ src/base/pdf-hash-helper.h 2009-06-27 23:19:51 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/12/28 02:10:50 jemarch"
+/* -*- mode: C -*- Time-stamp: "09/06/24 20:13:57 jemarch"
*
* File: pdf-hash-helper.h
* Date: Thu Jul 24 21:05:05 2008
@@ -73,6 +73,12 @@
pdf_hash_get_size (pdf_hash_t table, const char *key, pdf_size_t *elt);
pdf_status_t
+pdf_hash_add_bool (pdf_hash_t table, const char *key, const pdf_bool_t elt);
+
+pdf_status_t
+pdf_hash_get_bool (pdf_hash_t table, const char *key, pdf_bool_t *elt);
+
+pdf_status_t
pdf_hash_add_string (pdf_hash_t table, const char *key, const pdf_char_t *elt);
pdf_status_t
=== modified file 'src/base/pdf-stm-f-lzw.c'
--- src/base/pdf-stm-f-lzw.c 2009-01-11 21:37:29 +0000
+++ src/base/pdf-stm-f-lzw.c 2009-06-27 23:19:51 +0000
@@ -1,9 +1,9 @@
-/* -*- mode: C -*- Time-stamp: "09/01/11 22:04:33 jemarch"
+/* -*- mode: C -*- Time-stamp: "2009-06-28 00:40:49 raskolnikov"
*
* File: pdf-stm-f-lzw.c
* Date: Wed Aug 15 14:41:18 2007
*
- * GNU PDF Library - LWZ encoder/decoder filter
+ * GNU PDF Library - LZW encoder/decoder filter
*
*/
@@ -25,23 +25,23 @@
#include <string.h>
#include <pdf-alloc.h>
+#include <pdf-hash-helper.h>
#include <pdf-stm-f-lzw.h>
-#define MIN_BITSIZE 9
-#define MAX_BITSIZE 12
-#define MAX_DICTSIZE (1 << MAX_BITSIZE)
-
-#define MAX_COMPRESSION_FACTOR 1.5
-
-#define NULL_INDEX ~0U
-
-enum {
- LZW_RESET_CODE = 256,
- LZW_EOD_CODE,
- LZW_FIRST_CODE
-} lzw_special_codes;
-
-
+#define LZW_DEFAULT_EARLY_CHANGE 1
+
+#define LZW_CACHE_SIZE 16
+#define LZW_MIN_BITSIZE 9
+#define LZW_MAX_BITSIZE 12
+#define LZW_MAX_DICTSIZE (1 << LZW_MAX_BITSIZE)
+#define LZW_NULL_INDEX ~0U
+
+enum lzw_special_codes_e
+ {
+ LZW_RESET_CODE = 256,
+ LZW_EOD_CODE,
+ LZW_FIRST_CODE
+ };
/* -- LZW code output/input -- */
@@ -49,54 +49,79 @@
* Object to read and write codes of variable bitsize in a buffer.
* Warning: using both get and put functions may break the buffer.
*/
-typedef struct lzw_buffer_s
+struct lzw_buffer_s
{
- pdf_char_t* curp;
- pdf_char_t* endp;
+ pdf_buffer_t buf;
+ pdf_char_t cache [LZW_CACHE_SIZE];
+ int cache_rp;
+ int cache_wp;
unsigned long valbuf;
- unsigned valbits;
- unsigned bitsize;
- unsigned maxval;
-} lzw_buffer_t;
+ int valbits;
+ int bitsize;
+ int maxval;
+};
+typedef struct lzw_buffer_s* lzw_buffer_t;
static void
-lzw_buffer_init (lzw_buffer_t* b,
- pdf_char_t* ptr,
- int size,
+lzw_buffer_init (lzw_buffer_t b,
int bitsize)
{
- b->curp = ptr;
- b->endp = ptr + size;
+ b->buf = NULL;
b->valbuf = 0;
b->valbits = 0;
b->bitsize = bitsize;
b->maxval = (1 << bitsize) - 1;
-}
-
-static unsigned int
-lzw_buffer_get_code (lzw_buffer_t* b)
+ b->cache_wp = 0;
+ b->cache_rp = 0;
+}
+
+static void
+lzw_buffer_set (lzw_buffer_t b,
+ pdf_buffer_t buf)
+{
+ b->buf = buf;
+}
+
+static pdf_status_t
+lzw_buffer_get_code (lzw_buffer_t b,
+ unsigned int* code,
+ pdf_bool_t finish_p)
{
unsigned long r;
-
- while (b->valbits <= 24)
- {
- if (b->curp > b->endp)
- return NULL_INDEX;
-
- b->valbuf |= (unsigned long) *b->curp++ << (24 - b->valbits);
- b->valbits += 8;
- }
+
+ while (b->valbits <= 24 && !finish_p)
+ {
+ if (pdf_buffer_eob_p (b->buf))
+ {
+ return PDF_ENINPUT;
+ }
+ else
+ {
+ b->valbuf |=
+ (unsigned int) b->buf->data [b->buf->rp++] <<
+ (24 - b->valbits);
+
+ b->valbits += 8;
+ }
+ }
+
+ if (b->valbits < b->bitsize)
+ {
+ return PDF_EEOF;
+ }
r = b->valbuf >> (32 - b->bitsize);
b->valbuf <<= b->bitsize;
b->valbits -= b->bitsize;
-
- return r;
+
+ *code = r;
+
+ return PDF_OK;
}
/* Once finished, call with 0 as code value to flush the buffer. */
static void
-lzw_buffer_put_code (lzw_buffer_t* b,
+lzw_buffer_put_code (lzw_buffer_t b,
unsigned int code)
{
b->valbuf |= (unsigned long) code << (32 - b->bitsize - b->valbits);
@@ -104,17 +129,46 @@
while (b->valbits >= 8)
{
- *b->curp++ = b->valbuf >> 24;
+ if (pdf_buffer_full_p (b->buf))
+ {
+ b->cache [b->cache_wp++] = (pdf_char_t) (b->valbuf >> 24);
+ }
+ else
+ {
+ b->buf->data [b->buf->wp++] = (pdf_char_t) (b->valbuf >> 24);
+ }
b->valbuf <<= 8;
b->valbits -= 8;
}
}
+static pdf_status_t
+lzw_buffer_flush (lzw_buffer_t b)
+{
+ while (b->cache_rp != b->cache_wp &&
+ !pdf_buffer_full_p (b->buf))
+ {
+ b->buf->data [b->buf->wp++] = b->cache [b->cache_rp++];
+ }
+
+ if (pdf_buffer_full_p (b->buf))
+ {
+ return PDF_ENOUTPUT;
+ }
+
+ b->cache_wp = 0;
+ b->cache_rp = 0;
+
+ return PDF_OK;
+}
+
static int
-lzw_buffer_inc_bitsize (lzw_buffer_t* b)
+lzw_buffer_inc_bitsize (lzw_buffer_t b)
{
- if (b->bitsize == MAX_BITSIZE)
- return PDF_ERROR;
+ if (b->bitsize == LZW_MAX_BITSIZE)
+ {
+ return PDF_ERROR;
+ }
++b->bitsize;
b->maxval = (1 << b->bitsize) - 1;
@@ -123,20 +177,19 @@
}
static void
-lzw_buffer_set_bitsize (lzw_buffer_t* b,
+lzw_buffer_set_bitsize (lzw_buffer_t b,
int newsize)
{
b->bitsize = newsize;
b->maxval = (1 << newsize) - 1;
}
-
/* -- LZW dictionary handler -- */
/*
* The strings are stored in a non balanced ordered binary tree.
*/
-typedef struct lzw_string_s
+struct lzw_string_s
{
unsigned prefix; /* Prefix string code */
pdf_char_t suffix; /* Appended character */
@@ -144,44 +197,48 @@
unsigned first; /* First string with the same prefix. */
unsigned left; /* Next string with smaller suffix and same prefix. */
unsigned right; /* Next string with greater suffix and same prefix. */
-} lzw_string_t;
+};
+
+typedef struct lzw_string_s* lzw_string_t;
static void
-lzw_string_init (lzw_string_t* s)
+lzw_string_init (lzw_string_t s)
{
- memset(s, 0xFF, sizeof(lzw_string_t));
+ memset (s, 0xFF, sizeof (struct lzw_string_s));
}
-
-typedef struct lzw_dict_s
+struct lzw_dict_s
{
- lzw_string_t table[MAX_DICTSIZE];
+ struct lzw_string_s table [LZW_MAX_DICTSIZE];
unsigned size;
-} lzw_dict_t;
+};
+typedef struct lzw_dict_s* lzw_dict_t;
static void
-lzw_dict_init (lzw_dict_t* d)
+lzw_dict_init (lzw_dict_t d)
{
int i;
- memset(d->table, 0xFF, sizeof(lzw_string_t) * MAX_DICTSIZE);
+ memset (d->table,
+ 0xFF,
+ sizeof (struct lzw_string_s) * LZW_MAX_DICTSIZE);
for (i = 0; i < LZW_FIRST_CODE; i++)
{
- d->table[i].suffix = i;
+ d->table[i].suffix = (pdf_char_t) (i & 0xFF);
}
d->size = LZW_FIRST_CODE;
}
-static int
-lzw_dict_add (lzw_dict_t* d,
- lzw_string_t* s)
+static pdf_bool_t
+lzw_dict_add (lzw_dict_t d,
+ lzw_string_t s)
{
unsigned index;
int must_add;
- if (s->prefix == NULL_INDEX)
+ if (s->prefix == LZW_NULL_INDEX)
{
s->prefix = s->suffix;
return PDF_FALSE; /* The string is a basic character, found! */
@@ -189,7 +246,7 @@
index = d->table[s->prefix].first;
- if (index == NULL_INDEX)
+ if (index == LZW_NULL_INDEX)
{
d->table[s->prefix].first = d->size;
}
@@ -205,7 +262,7 @@
}
else if (s->suffix < d->table[index].suffix)
{
- if (d->table[index].left == NULL_INDEX)
+ if (d->table[index].left == LZW_NULL_INDEX)
{
d->table[index].left = d->size;
must_add = PDF_TRUE;
@@ -217,7 +274,7 @@
}
else
{
- if (d->table[index].right == NULL_INDEX)
+ if (d->table[index].right == LZW_NULL_INDEX)
{
d->table[index].right = d->size;
must_add = PDF_TRUE;
@@ -235,10 +292,14 @@
return PDF_TRUE;
}
-#define lzw_dict_reset lzw_dict_init
+static void
+lzw_dict_reset (lzw_dict_t dict)
+{
+ lzw_dict_init (dict);
+}
static void
-lzw_dict_fast_add (lzw_dict_t* d,
+lzw_dict_fast_add (lzw_dict_t d,
unsigned prefix,
pdf_char_t suffix)
{
@@ -248,309 +309,392 @@
}
static void
-lzw_dict_decode (lzw_dict_t* d,
+lzw_dict_decode (lzw_dict_t d,
unsigned code,
pdf_char_t** decode,
unsigned* size)
{
*size = 0;
- do {
- *(*decode)-- = d->table[code].suffix;
- ++(*size);
- code = d->table[code].prefix;
- } while (code != NULL_INDEX);
+ do
+ {
+ *(*decode)-- = d->table[code].suffix;
+ ++(*size);
+ code = d->table[code].prefix;
+ }
+ while (code != LZW_NULL_INDEX);
+
(*decode)++;
-
}
-/* -- The encoder -- */
-
-static int
-pdf_stm_f_lzw_encode (pdf_stm_f_lzw_data_t data,
- pdf_char_t *in,
- pdf_stm_pos_t in_size,
- pdf_char_t **out,
- pdf_stm_pos_t *out_size)
-{
- lzw_buffer_t buffer;
- lzw_dict_t dict;
- lzw_string_t string;
-
- /* Allocate buffer with enough space. */
- *out_size = in_size * MAX_COMPRESSION_FACTOR;
- if ((*out = (pdf_char_t *) pdf_alloc (*out_size)) == NULL)
+/* -- THE ENCODER -- */
+
+struct lzwenc_state_s
+{
+ /* cached params */
+ pdf_i32_t early_change;
+
+ /* encoding state */
+ pdf_bool_t must_reset_p;
+ struct lzw_buffer_s buffer;
+ struct lzw_dict_s dict;
+ struct lzw_string_s string;
+
+ pdf_bool_t really_finish_p;
+};
+typedef struct lzwenc_state_s* lzwenc_state_t;
+
+pdf_status_t
+pdf_stm_f_lzwenc_init (pdf_hash_t params,
+ void **ext_state)
+{
+ pdf_char_t *early_change_str;
+ lzwenc_state_t state;
+
+ state = pdf_alloc (sizeof (struct lzwenc_state_s));
+ if (!state)
{
- *out_size = 0;
return PDF_ERROR;
}
-
- /* Do the actual encoding. */
- lzw_buffer_init(&buffer, *out, *out_size, MIN_BITSIZE);
- lzw_dict_init(&dict);
- lzw_string_init(&string);
-
- lzw_buffer_put_code(&buffer, LZW_RESET_CODE);
-
- while (--in_size >= 0)
- {
- string.suffix = *in++;
-
- if (lzw_dict_add(&dict, &string))
+
+ state->early_change = 1; /* set default */
+
+ if (pdf_hash_key_p (params, "EarlyChange") == PDF_TRUE)
+ {
+ pdf_hash_get_string (params, "EarlyChange", &early_change_str);
+ if (early_change_str[0] == '0')
+ {
+ state->early_change = 0;
+ }
+ }
+
+ lzw_buffer_init (&state->buffer, LZW_MIN_BITSIZE);
+ lzw_dict_init (&state->dict);
+ lzw_string_init (&state->string);
+ state->must_reset_p = PDF_TRUE;
+ state->really_finish_p = PDF_FALSE;
+
+ *ext_state = state;
+ return PDF_OK;
+}
+
+pdf_status_t
+pdf_stm_f_lzwenc_apply (pdf_hash_t params,
+ void *ext_state,
+ pdf_buffer_t in,
+ pdf_buffer_t out,
+ pdf_bool_t finish_p)
+{
+ pdf_status_t ret;
+ lzwenc_state_t st;
+
+ ret = PDF_OK;
+ st = ext_state;
+ lzw_buffer_set (&st->buffer, out);
+
+ ret = lzw_buffer_flush (&st->buffer);
+ if (ret != PDF_OK)
+ {
+ return ret;
+ }
+
+ if (st->really_finish_p)
+ {
+ return PDF_EEOF;
+ }
+
+ if (st->must_reset_p)
+ {
+ lzw_buffer_put_code (&st->buffer, LZW_RESET_CODE);
+ st->must_reset_p = PDF_FALSE;
+ }
+
+ while (!pdf_buffer_eob_p (in) &&
+ !pdf_buffer_full_p (out))
+ {
+ st->string.suffix = in->data [in->rp++];
+ if (lzw_dict_add (&st->dict, &st->string))
{
- lzw_buffer_put_code(&buffer, string.prefix);
- string.prefix = string.suffix;
+ lzw_buffer_put_code (&st->buffer, st->string.prefix);
+ st->string.prefix = st->string.suffix;
- if (buffer.maxval - data->early_change == dict.size)
+ if (st->buffer.maxval - st->early_change == st->dict.size)
{
- if (!lzw_buffer_inc_bitsize(&buffer))
+ if (!lzw_buffer_inc_bitsize(&st->buffer))
{
- lzw_buffer_put_code(&buffer, LZW_RESET_CODE);
- lzw_buffer_set_bitsize(&buffer, MIN_BITSIZE);
- lzw_dict_reset(&dict);
+ lzw_buffer_put_code (&st->buffer, LZW_RESET_CODE);
+ lzw_buffer_set_bitsize (&st->buffer, LZW_MIN_BITSIZE);
+ lzw_dict_reset (&st->dict);
}
}
}
}
-
- lzw_buffer_put_code(&buffer, string.prefix);
- if (buffer.maxval - data->early_change == dict.size)
- lzw_buffer_inc_bitsize(&buffer);
- lzw_buffer_put_code(&buffer, LZW_EOD_CODE);
- lzw_buffer_put_code(&buffer, 0);
-
- /* Resize buffer to fit the data. */
- *out_size = (buffer.curp - *out);
- if ((*out = pdf_realloc(*out, *out_size)) == NULL)
- {
- *out_size = 0;
- return PDF_ERROR;
- }
-
- return PDF_OK;
-}
-
-/* -- The decoder -- */
-
-/* Utility to write to the output. */
-
-typedef struct lzw_writer_s
-{
- pdf_char_t* buf;
- pdf_char_t* cur;
- int writen;
- int allocated;
-} lzw_writer_t;
-
-static int
-lzw_writer_init (lzw_writer_t* s,
- int size)
-{
- if ((s->buf = pdf_alloc(size)) == NULL)
- {
- return PDF_ERROR;
- }
-
- s->cur = s->buf;
- s->writen = 0;
- s->allocated = size;
-
- return PDF_OK;
-}
-
-static int
-lzw_writer_fit (lzw_writer_t* s)
-{
- if ((s->buf = pdf_realloc(s->buf, s->writen)) == NULL)
- {
- return PDF_ERROR;
- }
-
- s->cur = s->buf + s->writen;
- s->allocated = s->writen;
-
- return PDF_OK;
-}
-
-static int
-lzw_writer_put (lzw_writer_t* s,
- pdf_char_t* data,
- unsigned size)
-{
- if (s->allocated < s->writen + size)
- {
- s->allocated = s->allocated * 2 + 1;
- if ((s->buf = pdf_realloc(s->buf, s->allocated)) == NULL)
- {
- return PDF_ERROR;
- }
- s->cur = s->buf + s->writen;
- }
-
- memcpy(s->cur, data, size);
- s->cur += size;
- s->writen += size;
-
- return PDF_OK;
-}
-
-static void
-lzw_writer_destroy (lzw_writer_t* s)
-{
- pdf_dealloc (s->buf);
-}
-
-static int
-pdf_stm_f_lzw_decode (pdf_stm_f_lzw_data_t data,
- pdf_char_t *in,
- pdf_stm_pos_t in_size,
- pdf_char_t **out,
- pdf_stm_pos_t *out_size)
-{
- pdf_char_t dec_buf[MAX_DICTSIZE];
+
+ if (finish_p)
+ {
+ lzw_buffer_put_code (&st->buffer, st->string.prefix);
+ if ((st->buffer.maxval - st->early_change) == st->dict.size)
+ {
+ lzw_buffer_inc_bitsize(&st->buffer);
+ }
+
+ lzw_buffer_put_code (&st->buffer, LZW_EOD_CODE);
+ lzw_buffer_put_code (&st->buffer, 0); /* flush */
+
+ if (pdf_buffer_full_p (out))
+ {
+ ret = PDF_ENOUTPUT;
+ }
+ else
+ {
+ ret = PDF_EEOF;
+ }
+
+ st->really_finish_p = PDF_TRUE;
+ }
+ else if (pdf_buffer_full_p (out))
+ {
+ ret = PDF_ENOUTPUT;
+ }
+ else if (pdf_buffer_eob_p (in))
+ {
+ ret = PDF_ENINPUT;
+ }
+
+ return ret;
+}
+
+pdf_status_t
+pdf_stm_f_lzwenc_dealloc_state (void *state)
+{
+ pdf_dealloc (state);
+ return PDF_OK;
+}
+
+/* -- THE DECODER -- */
+
+enum lzwdec_state
+ {
+ LZWDEC_STATE_START,
+ LZWDEC_STATE_CLEAN,
+ LZWDEC_STATE_WRITE,
+ LZWDEC_STATE_READ,
+ LZWDEC_STATE_LOOP_WRITE,
+ LZWDEC_STATE_LOOP_READ
+ };
+
+struct lzwdec_state_s
+{
+ /* cached params */
+ pdf_i32_t early_change;
+
+ /* state */
+ pdf_char_t dec_buf [LZW_MAX_DICTSIZE];
pdf_char_t* decoded;
- unsigned dec_size;
+ unsigned dec_size;
unsigned new_code;
unsigned old_code;
-
- lzw_buffer_t buffer;
- lzw_dict_t dict;
- lzw_writer_t writer;
-
- *out = NULL;
- *out_size = 0;
-
- if (lzw_writer_init(&writer, in_size) == PDF_ERROR)
- return PDF_ERROR;
-
- lzw_buffer_init(&buffer, in, in_size, MIN_BITSIZE);
- lzw_dict_init(&dict);
- old_code = NULL_INDEX;
-
- do {
- lzw_buffer_set_bitsize(&buffer, MIN_BITSIZE);
- lzw_dict_reset(&dict);
-
- do {
- new_code = lzw_buffer_get_code(&buffer);
- } while(new_code == LZW_RESET_CODE);
-
- if (new_code == NULL_INDEX)
- {
- lzw_writer_destroy(&writer);
- return PDF_ERROR;
- }
-
- if (new_code != LZW_EOD_CODE)
- {
- if (lzw_writer_put(&writer, (pdf_char_t*)&new_code, 1) == PDF_ERROR)
- return PDF_ERROR;
-
- old_code = new_code;
- new_code = lzw_buffer_get_code(&buffer);
- }
-
- while (new_code != LZW_EOD_CODE && new_code != LZW_RESET_CODE)
- {
- decoded = &(dec_buf[MAX_DICTSIZE-2]);
-
- if (new_code < dict.size) /* Is new code in the dict? */
- {
- lzw_dict_decode(&dict, new_code, &decoded, &dec_size);
- lzw_dict_fast_add(&dict, old_code, decoded[0]);
- }
- else
- {
- lzw_dict_decode(&dict, old_code, &decoded, &dec_size);
- lzw_dict_fast_add(&dict, old_code, decoded[0]);
- decoded[dec_size++] = decoded[0];
- }
-
- if (lzw_writer_put(&writer, decoded, dec_size) == PDF_ERROR)
- return PDF_ERROR;
-
- if (dict.size == buffer.maxval - 1 - data->early_change)
- if (!lzw_buffer_inc_bitsize(&buffer));
- /* break; We must wait for the reset code, don't reset yet. */
-
- old_code = new_code;
- new_code = lzw_buffer_get_code(&buffer);
-
- if (new_code == NULL_INDEX)
- {
- lzw_writer_destroy(&writer);
- return PDF_ERROR;
- }
- }
- } while (new_code != LZW_EOD_CODE);
-
- if (lzw_writer_fit(&writer) == PDF_ERROR)
- return PDF_ERROR;
-
- *out = writer.buf;
- *out_size = writer.writen;
-
- return PDF_OK;
-}
-
-
-/* -- PDF Filter functions --*/
-
-int
-pdf_stm_f_lzw_init (void **filter_data,
- void *conf_data)
-{
- pdf_stm_f_lzw_data_t *data;
- pdf_stm_f_lzw_conf_t conf;
-
- data = (pdf_stm_f_lzw_data_t *) filter_data;
- conf = (pdf_stm_f_lzw_conf_t) conf_data;
-
- /* Create the private data storage */
- *data =
- (pdf_stm_f_lzw_data_t) pdf_alloc (sizeof(struct pdf_stm_f_lzw_data_s));
- (*data)->mode = conf->mode;
- (*data)->early_change = conf->early_change;
-
- return PDF_OK;
-}
-
-int
-pdf_stm_f_lzw_apply (void *filter_data,
- pdf_char_t *in, pdf_stm_pos_t in_size,
- pdf_char_t **out, pdf_stm_pos_t *out_size)
-{
- pdf_stm_f_lzw_data_t data;
-
- data = (pdf_stm_f_lzw_data_t) filter_data;
- switch (data->mode)
- {
- case PDF_STM_F_LZW_MODE_ENCODE:
- {
- return pdf_stm_f_lzw_encode (data, in, in_size, out, out_size);
- }
- case PDF_STM_F_LZW_MODE_DECODE:
- {
- return pdf_stm_f_lzw_decode (data, in, in_size, out, out_size);
- }
+
+ /* flow managment */
+ enum lzwdec_state state_pos;
+ pdf_status_t tmp_ret;
+
+ struct lzw_buffer_s buffer;
+ struct lzw_dict_s dict;
+};
+typedef struct lzwdec_state_s* lzwdec_state_t;
+
+
+pdf_status_t
+pdf_stm_f_lzwdec_init (pdf_hash_t params,
+ void **ext_state)
+{
+ pdf_char_t *early_change_str;
+ lzwdec_state_t state;
+
+ state = pdf_alloc (sizeof (struct lzwdec_state_s));
+ if (!state)
+ {
+ return PDF_ERROR;
+ }
+
+ state->early_change = 1; /* set default */
+
+ if (pdf_hash_key_p (params, "EarlyChange") == PDF_TRUE)
+ {
+ pdf_hash_get_string (params, "EarlyChange", &early_change_str);
+ if (early_change_str[0] == '0')
+ {
+ state->early_change = 0;
+ }
+ }
+
+ lzw_buffer_init (&state->buffer, LZW_MIN_BITSIZE);
+ lzw_dict_init (&state->dict);
+ state->old_code = LZW_NULL_INDEX;
+ state->decoded = state->dec_buf + (LZW_MAX_DICTSIZE-2);
+ state->dec_size = 0;
+ state->state_pos = LZWDEC_STATE_START;
+ state->tmp_ret = 0;
+
+ *ext_state = state;
+ return PDF_OK;
+}
+
+pdf_status_t
+lzwdec_put_decoded (lzwdec_state_t st, pdf_buffer_t out)
+{
+ pdf_status_t ret;
+ pdf_size_t to_write;
+
+ ret = PDF_OK;
+
+ if (st->dec_size)
+ {
+ /* output the decoded string */
+ to_write = st->dec_size;
+ if (st->dec_size > (out->size - out->wp))
+ {
+ to_write = out->size - out->wp;
+ ret = PDF_ENOUTPUT;
+ }
+
+ memcpy (out->data + out->wp, st->decoded, to_write);
+ out->wp += to_write;
+ st->decoded += to_write;
+ st->dec_size -= to_write;
+ }
+
+ return ret;
+}
+
+pdf_status_t
+lzwdec_put_code (lzwdec_state_t st,
+ pdf_buffer_t out,
+ unsigned long code)
+{
+ if (pdf_buffer_full_p (out))
+ {
+ return PDF_ENOUTPUT;
+ }
+
+ out->data [out->wp++] = (pdf_char_t) (code & 0xFF);
+
+ return PDF_OK;
+}
+
+#define LZWDEC_CHECK(st, pos, what) \
+ do { (st)->state_pos = (pos); \
+ if (((st)->tmp_ret = (what)) != PDF_OK) \
+ { return ((st)->tmp_ret); } \
+ } while (0);
+
+pdf_status_t
+pdf_stm_f_lzwdec_apply (pdf_hash_t params,
+ void *ext_state,
+ pdf_buffer_t in,
+ pdf_buffer_t out,
+ pdf_bool_t finish_p)
+{
+ lzwdec_state_t st;
+
+ st = ext_state;
+ lzw_buffer_set (&st->buffer, in);
+
+ switch (st->state_pos)
+ {
+ case LZWDEC_STATE_START:
+ break;
+ case LZWDEC_STATE_CLEAN:
+ goto lzwdec_state_clean;
+ case LZWDEC_STATE_WRITE:
+ goto lzwdec_state_write;
+ case LZWDEC_STATE_READ:
+ goto lzwdec_state_read;
+ case LZWDEC_STATE_LOOP_WRITE:
+ goto lzwdec_state_loop_write;
+ case LZWDEC_STATE_LOOP_READ:
+ goto lzwdec_state_loop_read;
default:
- {
- return PDF_ERROR;
- }
- }
-
- /* Not reached */
+ break;
+ }
+
+ do
+ {
+ /* need a reset */
+ lzw_buffer_set_bitsize (&st->buffer, LZW_MIN_BITSIZE);
+ lzw_dict_reset (&st->dict);
+
+ do
+ {
+ lzwdec_state_clean:
+ LZWDEC_CHECK (st, LZWDEC_STATE_CLEAN,
+ lzw_buffer_get_code (&st->buffer, &st->new_code,
finish_p));
+ }
+ while (st->new_code == LZW_RESET_CODE);
+
+ if (st->new_code != LZW_EOD_CODE)
+ {
+ lzwdec_state_write:
+ LZWDEC_CHECK (st, LZWDEC_STATE_WRITE,
+ lzwdec_put_code (st, out, st->new_code));
+
+ st->old_code = st->new_code;
+ lzwdec_state_read:
+ LZWDEC_CHECK (st, LZWDEC_STATE_READ,
+ lzw_buffer_get_code (&st->buffer, &st->new_code,
finish_p));
+ }
+
+ while (st->new_code != LZW_EOD_CODE &&
+ st->new_code != LZW_RESET_CODE)
+ {
+ st->decoded = st->dec_buf + (LZW_MAX_DICTSIZE-2);
+
+ /* Is new code in the dict? */
+ if (st->new_code < st->dict.size)
+ {
+ lzw_dict_decode (&st->dict, st->new_code,
+ &st->decoded, &st->dec_size);
+ lzw_dict_fast_add (&st->dict, st->old_code, st->decoded[0]);
+ }
+ else
+ {
+ lzw_dict_decode (&st->dict, st->old_code,
+ &st->decoded, &st->dec_size);
+ lzw_dict_fast_add (&st->dict, st->old_code, st->decoded[0]);
+ st->decoded [st->dec_size++] = st->decoded [0];
+ }
+
+ /* output the decoded string */
+ lzwdec_state_loop_write:
+ LZWDEC_CHECK (st, LZWDEC_STATE_LOOP_WRITE,
+ lzwdec_put_decoded (st, out));
+
+ if (st->dict.size == st->buffer.maxval - 1 - st->early_change)
+ {
+ if (!lzw_buffer_inc_bitsize (&st->buffer));
+ /* break; We must wait for the reset code, don't reset yet. */
+ }
+
+ /* get next code */
+ st->old_code = st->new_code;
+ lzwdec_state_loop_read:
+ LZWDEC_CHECK (st, LZWDEC_STATE_LOOP_READ,
+ lzw_buffer_get_code (&st->buffer, &st->new_code,
finish_p));
+ }
+ }
+ while (st->new_code != LZW_EOD_CODE);
+
+ st->state_pos = LZWDEC_STATE_START;
+
+ return PDF_EEOF;
}
-int
-pdf_stm_f_lzw_dealloc (void **filter_data)
+pdf_status_t
+pdf_stm_f_lzwdec_dealloc_state (void *state)
{
- pdf_stm_f_lzw_data_t *data;
-
- data = (pdf_stm_f_lzw_data_t *) filter_data;
- pdf_dealloc (*data);
-
+ pdf_dealloc (state);
return PDF_OK;
}
=== modified file 'src/base/pdf-stm-f-lzw.h'
--- src/base/pdf-stm-f-lzw.h 2009-01-11 21:37:29 +0000
+++ src/base/pdf-stm-f-lzw.h 2009-06-27 23:19:51 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "09/01/11 22:04:37 jemarch"
+/* -*- mode: C -*- Time-stamp: "2009-06-24 20:18:48 raskolnikov"
*
* File: pdf-stm-f-lzw.h
* Date: Wed Aug 15 14:13:20 2007
@@ -27,54 +27,31 @@
#define PDF_STM_F_LZW_H
#include <config.h>
-#include <pdf-base.h>
-
-/* Configuration data */
-
-/* BEGIN PUBLIC */
-
-enum pdf_stm_f_lzw_mode_t
-{
- PDF_STM_F_LZW_MODE_ENCODE,
- PDF_STM_F_LZW_MODE_DECODE
-};
-
-/* END PUBLIC */
-
-struct pdf_stm_f_lzw_conf_s
-{
- int mode;
- int early_change; /* An indication of when to increase the code
- length. If the value of this entry is 0, code
- length increases are postponed as long as
- possible. If the value is 1, code length
- increases occur one code early. This
- parameter is included because LZW sample code
- distributed by some vendors increases the
- code length one code earlier than necessary.
-
- Default value: 1 */
-};
-
-typedef struct pdf_stm_f_lzw_conf_s *pdf_stm_f_lzw_conf_t;
-
-/* Private data */
-
-struct pdf_stm_f_lzw_data_s
-{
- int mode;
- int early_change;
-};
-
-typedef struct pdf_stm_f_lzw_data_s *pdf_stm_f_lzw_data_t;
+
+#include <pdf-types.h>
+#include <pdf-hash.h>
/* Filter API implementation */
-int pdf_stm_f_lzw_init (void **filter_data, void *conf_data);
-int pdf_stm_f_lzw_apply (void *filter_data,
- pdf_char_t *in, pdf_stm_pos_t in_size,
- pdf_char_t **out, pdf_stm_pos_t *out_size);
-int pdf_stm_f_lzw_dealloc (void **filter_data);
+pdf_status_t pdf_stm_f_lzwenc_init (pdf_hash_t params,
+ void **state);
+pdf_status_t pdf_stm_f_lzwenc_apply (pdf_hash_t params,
+ void *state,
+ pdf_buffer_t in,
+ pdf_buffer_t out,
+ pdf_bool_t finish_p);
+
+pdf_status_t pdf_stm_f_lzwdec_init (pdf_hash_t params,
+ void **state);
+pdf_status_t pdf_stm_f_lzwdec_apply (pdf_hash_t params,
+ void *state,
+ pdf_buffer_t in,
+ pdf_buffer_t out,
+ pdf_bool_t finish_p);
+
+pdf_status_t pdf_stm_f_lzwdec_dealloc_state (void *state);
+
+pdf_status_t pdf_stm_f_lzwenc_dealloc_state (void *state);
#endif /* pdf_stm_f_lzw.h */
=== modified file 'src/base/pdf-stm-filter.c'
--- src/base/pdf-stm-filter.c 2009-05-19 13:26:02 +0000
+++ src/base/pdf-stm-filter.c 2009-06-27 23:19:51 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "09/05/19 15:13:06 jemarch"
+/* -*- mode: C -*- Time-stamp: "2009-06-28 00:33:54 raskolnikov"
*
* File: pdf-stm-filter.c
* Date: Thu Jun 12 22:13:31 2008
@@ -162,6 +162,20 @@
new->impl.dealloc_state_fn = pdf_stm_f_md5enc_dealloc_state;
break;
}
+ case PDF_STM_FILTER_LZW_ENC:
+ {
+ new->impl.init_fn = pdf_stm_f_lzwenc_init;
+ new->impl.apply_fn = pdf_stm_f_lzwenc_apply;
+ new->impl.dealloc_state_fn = pdf_stm_f_lzwenc_dealloc_state;
+ break;
+ }
+ case PDF_STM_FILTER_LZW_DEC:
+ {
+ new->impl.init_fn = pdf_stm_f_lzwdec_init;
+ new->impl.apply_fn = pdf_stm_f_lzwdec_apply;
+ new->impl.dealloc_state_fn = pdf_stm_f_lzwdec_dealloc_state;
+ break;
+ }
#if defined(HAVE_LIBJBIG2DEC)
case PDF_STM_FILTER_JBIG2_DEC:
{
=== modified file 'src/base/pdf-stm-filter.h'
--- src/base/pdf-stm-filter.h 2009-01-12 13:30:36 +0000
+++ src/base/pdf-stm-filter.h 2009-06-27 23:19:51 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "09/01/11 22:03:22 jemarch"
+/* -*- mode: C -*- Time-stamp: "2009-06-28 00:32:10 raskolnikov"
*
* File: pdf-stm-filter.h
* Date: Thu Jun 12 22:05:06 2008
@@ -37,6 +37,7 @@
#include <pdf-stm-f-v2.h>
#include <pdf-stm-f-aesv2.h>
#include <pdf-stm-f-md5.h>
+#include <pdf-stm-f-lzw.h>
#if defined(HAVE_LIBZ)
# include <pdf-stm-f-flate.h>
@@ -74,7 +75,9 @@
PDF_STM_FILTER_AESV2_DEC,
PDF_STM_FILTER_V2_ENC,
PDF_STM_FILTER_V2_DEC,
- PDF_STM_FILTER_MD5_ENC
+ PDF_STM_FILTER_MD5_ENC,
+ PDF_STM_FILTER_LZW_DEC,
+ PDF_STM_FILTER_LZW_ENC
};
/* END PUBLIC */
=== modified file 'torture/unit/base/stm/pdf-stm-write.c'
--- torture/unit/base/stm/pdf-stm-write.c 2009-05-15 17:55:40 +0000
+++ torture/unit/base/stm/pdf-stm-write.c 2009-06-27 23:19:51 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "2009-05-15 13:53:39 gerel"
+/* -*- mode: C -*- Time-stamp: "2009-06-28 01:16:15 raskolnikov"
*
* File: pdf-stm-write.c
* Date: Sun Sep 21 16:37:27 2008
@@ -30,6 +30,44 @@
#include <pdf.h>
/*
+ * Fixture: mem_stm_fixture.
+ * Description:
+ * Common data for memory stream based tests.
+ */
+struct
+{
+ pdf_stm_t stm;
+ pdf_char_t *buf;
+} mem_stm_fixture;
+
+#define MEM_STM_FIXTURE_BUFFER_SIZE 1024
+#define MEM_STM_FIXTURE_CACHE_SIZE 1
+
+static void
+mem_stm_fixture_setup ()
+{
+ pdf_status_t ret;
+
+ mem_stm_fixture.buf = pdf_alloc (MEM_STM_FIXTURE_BUFFER_SIZE);
+ fail_if (mem_stm_fixture.buf == NULL);
+
+ ret = pdf_stm_mem_new (mem_stm_fixture.buf,
+ MEM_STM_FIXTURE_BUFFER_SIZE,
+ MEM_STM_FIXTURE_CACHE_SIZE,
+ PDF_STM_WRITE,
+ &mem_stm_fixture.stm);
+ fail_if (ret != PDF_OK);
+}
+
+static void
+mem_stm_fixture_teardown ()
+{
+ pdf_stm_destroy (mem_stm_fixture.stm);
+ pdf_dealloc (mem_stm_fixture.buf);
+}
+
+
+/*
* Test: pdf_stm_write_001
* Description:
* Write some bytes to a write memory stream.
@@ -871,6 +909,82 @@
END_TEST
+
+/*
+ * Test: pdf_stm_write_015
+ * Description:
+ * Create a memory-based writing stream and attach an LZW filter
+ * encoder to it.
+ * Success condition:
+ * The encoded data should be correct.
+ */
+START_TEST (pdf_stm_write_015)
+{
+ pdf_status_t ret;
+ pdf_hash_t params;
+ pdf_size_t tmp = 0;
+
+ pdf_char_t *decoded =
+ "-----A---B";
+ pdf_char_t *encoded =
+ "\x80\x0B\x60\x50\x22\x0C\x0C\x85\x01";
+
+
+ /* Create the filter */
+ pdf_hash_new (NULL, ¶ms);
+ fail_if (pdf_stm_install_filter (mem_stm_fixture.stm,
+ PDF_STM_FILTER_LZW_ENC,
+ params)
+ != PDF_OK);
+
+ /* Write and test some stuff */
+ ret = pdf_stm_write (mem_stm_fixture.stm, decoded, 10, &tmp);
+ fail_if (ret == PDF_ERROR);
+ fail_if (pdf_stm_flush (mem_stm_fixture.stm, PDF_TRUE, &tmp) == PDF_ERROR);
+ fail_if (memcmp (mem_stm_fixture.buf, encoded, 9) != 0);
+
+ /* Cleanup */
+ pdf_hash_destroy (params);
+}
+END_TEST
+
+/*
+ * Test: pdf_stm_write_015
+ * Description:
+ * Create a memory-based writing stream and attach an LZW filter
+ * encoder to it.
+ * Success condition:
+ * The encoded data should be correct.
+ */
+START_TEST (pdf_stm_write_016)
+{
+ pdf_status_t ret;
+ pdf_hash_t params;
+ pdf_size_t tmp = 0;
+
+ pdf_char_t *encoded =
+ "\x80\x0B\x60\x50\x22\x0C\x0C\x85\x01";
+ pdf_char_t *decoded =
+ "-----A---B";
+
+ /* Create the filter */
+ pdf_hash_new (NULL, ¶ms);
+ fail_if (pdf_stm_install_filter (mem_stm_fixture.stm,
+ PDF_STM_FILTER_LZW_DEC,
+ params)
+ != PDF_OK);
+
+ /* Test some data */
+ ret = pdf_stm_write (mem_stm_fixture.stm, encoded, 9, &tmp);
+ fail_if (ret == PDF_ERROR);
+ fail_if (pdf_stm_flush (mem_stm_fixture.stm, PDF_TRUE, &tmp) == PDF_ERROR);
+ fail_if (memcmp (mem_stm_fixture.buf, decoded, 10) != 0);
+
+ /* Cleanup */
+ pdf_hash_destroy (params);
+}
+END_TEST
+
/*
* Test case creation function
*/
@@ -879,6 +993,10 @@
{
TCase *tc = tcase_create ("pdf_stm_write");
+ tcase_add_checked_fixture(tc,
+ mem_stm_fixture_setup,
+ mem_stm_fixture_teardown);
+
tcase_add_test(tc, pdf_stm_write_001);
tcase_add_test(tc, pdf_stm_write_002);
tcase_add_test(tc, pdf_stm_write_003);
@@ -896,6 +1014,8 @@
tcase_add_test(tc, pdf_stm_write_012);
tcase_add_test(tc, pdf_stm_write_013);
tcase_add_test(tc, pdf_stm_write_014);
+ tcase_add_test(tc, pdf_stm_write_015);
+ tcase_add_test(tc, pdf_stm_write_016);
return tc;
}
=== modified file 'utils/Makefile.am'
--- utils/Makefile.am 2009-06-24 19:25:52 +0000
+++ utils/Makefile.am 2009-06-27 23:19:51 +0000
@@ -22,7 +22,7 @@
ICONV_LIBS = -liconv
endif #ICONV
-bin_PROGRAMS = pdf-filter pdf-tokeniser
+bin_PROGRAMS = pdf-filter
LDADD = $(top_builddir)/src/libgnupdf.la \
$(ICONV_LIBS)
@@ -31,6 +31,6 @@
-I$(top_srcdir)/src/base -I $(top_srcdir)/src/object
pdf_filter_SOURCES = pdf-filter.h pdf-filter.c
-pdf_tokeniser__SOURCES = pdf-tokeniser.c
+# pdf_tokeniser__SOURCES = pdf-tokeniser.c
# End of Makefile.am
=== modified file 'utils/pdf-filter.c'
--- utils/pdf-filter.c 2009-06-24 19:25:52 +0000
+++ utils/pdf-filter.c 2009-06-27 23:19:51 +0000
@@ -58,11 +58,12 @@
{"null", no_argument, NULL, NULL_FILTER_ARG},
{"ahexdec", no_argument, NULL, ASCIIHEXDEC_FILTER_ARG},
{"ahexenc", no_argument, NULL, ASCIIHEXENC_FILTER_ARG},
+ {"lzwenc", no_argument, NULL, LZWENC_FILTER_ARG},
+ {"lzwdec", no_argument, NULL, LZWDEC_FILTER_ARG},
+ {"lzw-earlychange", no_argument, NULL, LZW_EARLYCHANGE_ARG},
#if 0
{"a85dec", no_argument, NULL, ASCII85DEC_FILTER_ARG},
{"a85enc", no_argument, NULL, ASCII85ENC_FILTER_ARG},
- {"lzwenc", no_argument, NULL, LZWENC_FILTER_ARG},
- {"lzwdec", no_argument, NULL, LZWDEC_FILTER_ARG},
{"cfaxdec", no_argument, NULL, CCITTFAXDEC_FILTER_ARG},
{"jxpdec", no_argument, NULL, JXPDEC_FILTER_ARG},
{"predenc", no_argument, NULL, PREDENC_FILTER_ARG},
@@ -108,12 +109,12 @@
available filters\n\
--null use the NULL filter\n\
--ahexdec use the ASCII Hex decoder filter\n\
- --ahexenc use the ASCII Hex encoder filter\n"
+ --ahexenc use the ASCII Hex encoder filter\n\
+ --lzwenc use the LZW encoder filter\n\
+ --lzwdec use the LZW decoder filter\n"
#if 0
" --a85dec use the ASCII 85 decoder filter\n\
--a85enc use the ASCII 85 encoder filter\n\
- --lzwenc use the LZW encoder filter\n\
- --lzwdec use the LZW decoder filter\n
--jxpdec use the JXP decoder filter\n\
--predenc use the predictor encoder filter\n\
--preddec use the predictor decoder filter\n"
@@ -139,14 +140,15 @@
--version show pdf-filter version and exit\n\
\nfilter properties\n"
#if 0
-" --lzw-earlychange toggles earlychange for next lzw
filters\n\
+"
--preddec-type=NUM code for next preddec filters type\n\
--predenc-type=NUM code for next predenc filters type\n\
--pred-colors=NUM next predictors colors per sample\n\
--pred-bpc=NUM next predictors bits per color
component\n\
--pred-columns=NUM next predictors number of samples per
row\n"
#endif /* 0 */
-" --jbig2dec-globals=FILE file containing global segments\n\
+" --lzw-earlychange toggles earlychange for next lzw
filters\n\
+ --jbig2dec-globals=FILE file containing global segments\n\
";
char *pdf_filter_help_msg = "";
@@ -448,6 +450,7 @@
char *key = NULL;
pdf_size_t jbig2dec_global_segments_size = 0;
pdf_status_t status;
+ pdf_bool_t lzw_earlychange = PDF_FALSE;
/* Initialize the crypt module */
if (pdf_crypt_init () != PDF_OK)
@@ -554,14 +557,6 @@
{
break;
}
- case LZWENC_FILTER_ARG:
- {
- break;
- }
- case LZWDEC_FILTER_ARG:
- {
- break;
- }
case CCITTFAXDEC_FILTER_ARG:
{
break;
@@ -591,6 +586,57 @@
break;
}
#endif /* 0 */
+ case LZW_EARLYCHANGE_ARG:
+ {
+ lzw_earlychange = PDF_TRUE;
+ break;
+ }
+ case LZWENC_FILTER_ARG:
+ {
+ ret = pdf_hash_new (NULL, &filter_params);
+ if (ret != PDF_OK)
+ {
+ pdf_error (ret, stderr, "while creating the lzwenc filter
parameters hash table");
+ exit (1);
+ }
+
+ pdf_hash_add_bool (filter_params, "EarlyChange", lzw_earlychange);
+
+ status = pdf_stm_install_filter (stm,
+ PDF_STM_FILTER_LZW_ENC,
+ filter_params);
+
+ if (status != PDF_OK)
+ {
+ pdf_error (status, stderr, "while creating the LZW encoder
filter");
+ exit (1);
+ }
+
+ break;
+ }
+ case LZWDEC_FILTER_ARG:
+ {
+ ret = pdf_hash_new (NULL, &filter_params);
+ if (ret != PDF_OK)
+ {
+ pdf_error (ret, stderr, "while creating the lzwdec filter
parameters hash table");
+ exit (1);
+ }
+
+ pdf_hash_add_bool (filter_params, "EarlyChange", lzw_earlychange);
+
+ status = pdf_stm_install_filter (stm,
+ PDF_STM_FILTER_LZW_DEC,
+ filter_params);
+
+ if (status != PDF_OK)
+ {
+ pdf_error (status, stderr, "while creating the LZW decoder
filter");
+ exit (1);
+ }
+
+ break;
+ }
#ifdef HAVE_LIBZ
case FLATEDEC_FILTER_ARG:
{
=== modified file 'utils/pdf-filter.h'
--- utils/pdf-filter.h 2009-05-06 17:54:48 +0000
+++ utils/pdf-filter.h 2009-06-27 23:19:51 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "09/05/06 19:46:33 jemarch"
+/* -*- mode: C -*- Time-stamp: "09/06/24 19:37:20 jemarch"
*
* File: pdf-filter.h
* Date: Tue Jul 10 18:40:55 2007
@@ -46,8 +46,6 @@
#if 0
ASCII85DEC_FILTER_ARG,
ASCII85ENC_FILTER_ARG,
- LZWENC_FILTER_ARG,
- LZWDEC_FILTER_ARG,
CCITTFAXDEC_FILTER_ARG,
JXPDEC_FILTER_ARG,
PREDENC_FILTER_ARG,
@@ -67,6 +65,9 @@
JBIG2DEC_GLOBAL_SEGMENTS_ARG,
JBIG2DEC_PAGE_SIZE,
#endif /* HAVE_LIBJBIG2DEC */
+ LZWENC_FILTER_ARG,
+ LZWDEC_FILTER_ARG,
+ LZW_EARLYCHANGE_ARG,
MD5ENC_FILTER_ARG,
KEY_ARG,
AESENC_FILTER_ARG,
# Begin bundle
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
lzw-28-06-09.patch.sig
Description: PGP signature
- [pdf-devel] LZW filter re-implementation,
Juan Pedro Bolivar Puente <=