Only in libgnupdf: aclocal.m4 Only in libgnupdf: autom4te.cache diff -rup orig/libgnupdf/ChangeLog libgnupdf/ChangeLog --- orig/libgnupdf/ChangeLog 2007-08-15 15:07:43.000000000 +0200 +++ libgnupdf/ChangeLog 2007-09-05 18:08:51.000000000 +0200 @@ -1,3 +1,15 @@ + +2007-09-05 Juan Pedro BolĂ­var Puente + + * src/pdf_stm_f_lzw.c: Fully implemented the LZW filter for both + encoding and decoding. + + * src/pdf_stm_f_pred.c: Solved a bug in the order in which bytes + where written when packing tiff pixels. + + * utils/pdf_filter.c: Now lzw and predictor filters can get their + arguments from the command line. + 2007-08-15 Jose E. Marchesi * src/pdf_stm.c (pdf_stm_install_lzwenc_filter): New function. Only in libgnupdf: config.guess Only in libgnupdf: config.sub Only in libgnupdf: configure diff -rup orig/libgnupdf/CVS/Entries libgnupdf/CVS/Entries --- orig/libgnupdf/CVS/Entries 2007-09-05 18:13:15.000000000 +0200 +++ libgnupdf/CVS/Entries 2007-09-05 18:11:45.000000000 +0200 @@ -11,4 +11,9 @@ /depcomp/1.1/Thu Jul 5 18:52:12 2007// /install-sh/1.1/Thu Jul 5 18:52:13 2007// /missing/1.1/Thu Jul 5 18:52:13 2007// -D +D/doc//// +D/lib//// +D/m4//// +D/src//// +D/torture//// +D/utils//// Only in orig/libgnupdf/CVS: Entries.Log Only in libgnupdf/doc: gnupdf.info Only in libgnupdf/doc: Makefile.in Only in libgnupdf/lib: Makefile.in Only in libgnupdf: ltmain.sh Only in libgnupdf: Makefile.in Only in libgnupdf/src: config.h.in Only in libgnupdf/src: Makefile.in diff -rup orig/libgnupdf/src/pdf_stm_f_lzw.c libgnupdf/src/pdf_stm_f_lzw.c --- orig/libgnupdf/src/pdf_stm_f_lzw.c 2007-08-15 15:07:43.000000000 +0200 +++ libgnupdf/src/pdf_stm_f_lzw.c 2007-09-05 17:18:10.000000000 +0200 @@ -30,12 +30,475 @@ #include #include -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); -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); +#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; + + + +/* -- LZW code output/input -- */ + +/* + * 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 +{ + pdf_char_t* curp; + pdf_char_t* endp; + unsigned long valbuf; + unsigned valbits; + unsigned bitsize; + unsigned maxval; +} lzw_buffer_t; + +static void +lzw_buffer_init (lzw_buffer_t* b, + pdf_char_t* ptr, + int size, + int bitsize) +{ + b->curp = ptr; + b->endp = ptr + size; + 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) +{ + 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; + } + + r = b->valbuf >> (32 - b->bitsize); + b->valbuf <<= b->bitsize; + b->valbits -= b->bitsize; + + return r; +} + +/* Once finished, call with 0 as code value to flush the buffer. */ +static void +lzw_buffer_put_code (lzw_buffer_t* b, + unsigned int code) +{ + b->valbuf |= (unsigned long) code << (32 - b->bitsize - b->valbits); + b->valbits += b->bitsize; + + while (b->valbits >= 8) + { + *b->curp++ = b->valbuf >> 24; + b->valbuf <<= 8; + b->valbits -= 8; + } +} + +static int +lzw_buffer_inc_bitsize (lzw_buffer_t* b) +{ + if (b->bitsize == MAX_BITSIZE) + return PDF_ERROR; + + ++b->bitsize; + b->maxval = (1 << b->bitsize) - 1; + + return PDF_OK; +} + +static void +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 +{ + unsigned prefix; /* Prefix string code */ + pdf_char_t suffix; /* Appended character */ + + 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; + +static void +lzw_string_init (lzw_string_t* s) +{ + memset(s, 0xFF, sizeof(lzw_string_t)); +} + + +typedef struct lzw_dict_s +{ + lzw_string_t table[MAX_DICTSIZE]; + unsigned size; +} lzw_dict_t; + +static void +lzw_dict_init (lzw_dict_t* d) +{ + int i; + + memset(d->table, 0xFF, sizeof(lzw_string_t) * MAX_DICTSIZE); + + for (i = 0; i < LZW_FIRST_CODE; i++) + { + d->table[i].suffix = i; + } + + d->size = LZW_FIRST_CODE; +} + +static int +lzw_dict_add (lzw_dict_t* d, + lzw_string_t* s) +{ + unsigned index; + int must_add; + + if (s->prefix == NULL_INDEX) + { + s->prefix = s->suffix; + return PDF_FALSE; /* The string is a basic character, found! */ + } + + index = d->table[s->prefix].first; + + if (index == NULL_INDEX) + { + d->table[s->prefix].first = d->size; + } + else + { + must_add = PDF_FALSE; + while (!must_add) + { + if (s->suffix == d->table[index].suffix) + { + s->prefix = index; + return PDF_FALSE; /* The string is already in the table, found! */ + } + else if (s->suffix < d->table[index].suffix) + { + if (d->table[index].left == NULL_INDEX) + { + d->table[index].left = d->size; + must_add = PDF_TRUE; + } + else + { + index = d->table[index].left; + } + } + else + { + if (d->table[index].right == NULL_INDEX) + { + d->table[index].right = d->size; + must_add = PDF_TRUE; + } + else + { + index = d->table[index].right; + } + } + } + } + + d->table[d->size++] = *s; + + return PDF_TRUE; +} + +#define lzw_dict_reset lzw_dict_init + +static void +lzw_dict_fast_add (lzw_dict_t* d, + unsigned prefix, + pdf_char_t suffix) +{ + d->table[d->size].prefix = prefix; + d->table[d->size].suffix = suffix; + d->size++; +} + +static void +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); + (*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 *) xmalloc (*out_size)) == NULL) + { + *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)) + { + lzw_buffer_put_code(&buffer, string.prefix); + string.prefix = string.suffix; + + if (buffer.maxval - data->early_change == dict.size) + { + if (!lzw_buffer_inc_bitsize(&buffer)) + { + lzw_buffer_put_code(&buffer, LZW_RESET_CODE); + lzw_buffer_set_bitsize(&buffer, MIN_BITSIZE); + lzw_dict_reset(&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 = xrealloc(*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 = xmalloc(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 = xrealloc(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 = xrealloc(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) +{ + free(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]; + pdf_char_t* decoded; + 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, @@ -50,6 +513,7 @@ pdf_stm_f_lzw_init (void **filter_data, /* Create the private data storage */ *data = (pdf_stm_f_lzw_data_t) xmalloc (sizeof(struct pdf_stm_f_lzw_data_s)); + (*data)->mode = conf->mode; (*data)->early_change = conf->early_change; return PDF_OK; @@ -93,39 +557,4 @@ pdf_stm_f_lzw_dealloc (void **filter_dat return PDF_OK; } -/* Private functions */ - -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) -{ - *out = (pdf_char_t *) xmalloc (in_size); - memcpy (*out, - in, - in_size); - *out_size = in_size; - - return PDF_OK; -} - -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) -{ - *out = (pdf_char_t *) xmalloc (in_size); - memcpy (*out, - in, - in_size); - *out_size = in_size; - - return PDF_OK; -} - - /* End of pdf_stm_f_lzw.c */ diff -rup orig/libgnupdf/src/pdf_stm_f_pred.c libgnupdf/src/pdf_stm_f_pred.c --- orig/libgnupdf/src/pdf_stm_f_pred.c 2007-07-28 21:02:31.000000000 +0200 +++ libgnupdf/src/pdf_stm_f_pred.c 2007-09-05 17:57:07.000000000 +0200 @@ -42,49 +42,52 @@ (pred) == PDF_STM_F_PREDENC_PNG_PAETH_ALL_ROWS || \ (pred) == PDF_STM_F_PREDENC_PNG_OPTIMUM) -/* Dirty util */ -typedef struct bit_ptr_s +/* + * This is a bit level pointer object optimized for the needs in the + * predictor class optimized for its usage within the needs of the predictor + * coding and decoding clases. + * + * This adds a limitation: the block_size must be between 1 and 8 and must be + * a power of two. + * + * TODO: Check endianess. + */ +typedef struct pred_bit_ptr_s { pdf_char_t* ptr; int offset; int mask; - int block_size; -} bit_ptr_t; + int block_size; +} pred_bit_ptr_t; static void -bit_ptr_init (bit_ptr_t* bp, +pred_bit_ptr_init (pred_bit_ptr_t* bp, pdf_char_t* ptr, int block_size) { - int i; bp->ptr = ptr; - bp->offset = 0; + bp->offset = 8 - block_size; bp->block_size = block_size; - bp->mask = 0; - for (i = 0; i < bp->block_size; i++) - { - bp->mask <<= 1; - bp->mask |= 1; - } + bp->mask = (~0U << bp->block_size); + bp->mask = ~bp->mask; } -#define BIT_PTR_ADV(bp) \ - if ((bp).offset + (bp).block_size < 8) \ +#define PRED_BIT_PTR_ADV(bp) \ + if ((bp).offset > 0) \ { \ - (bp).offset += (bp).block_size; \ + (bp).offset -= (bp).block_size; \ } \ else \ { \ (bp).ptr++; \ - (bp).offset = 0; \ + (bp).offset = 8 - (bp).block_size; \ } - -#define BIT_PTR_GET(bp) \ - ((*(bp).ptr & ((bp).mask << bp.offset)) >> bp.offset) -#define BIT_PTR_SET(bp, e) \ - (*(bp).ptr = (*(bp).ptr & ~((bp).mask << (bp).offset)) | ((e) << (bp).offset)) +#define PRED_BIT_PTR_GET(bp) \ + ((*(bp).ptr >> (bp).offset) & (bp).mask) +#define PRED_BIT_PTR_SET(bp, e) \ + (*(bp).ptr = (*(bp).ptr & ~((bp).mask << (bp).offset)) | (((e) & (bp).mask) << (bp).offset)) int pdf_stm_f_pred_init (void **filter_data, @@ -314,28 +317,28 @@ encode_row_sub_colorl8 (pdf_char_t *cur, { int i; int j; - bit_ptr_t this; - bit_ptr_t next; - bit_ptr_t sout; - - bit_ptr_init (&this, cur, data->bits_per_component); - bit_ptr_init (&next, cur, data->bits_per_component); - bit_ptr_init (&sout, out, data->bits_per_component); + pred_bit_ptr_t this; + pred_bit_ptr_t next; + pred_bit_ptr_t sout; + + pred_bit_ptr_init (&this, cur, data->bits_per_component); + pred_bit_ptr_init (&next, cur, data->bits_per_component); + pred_bit_ptr_init (&sout, out, data->bits_per_component); for (j = 0; j < data->colors; j++) { - BIT_PTR_SET(sout, BIT_PTR_GET(next)); - BIT_PTR_ADV(sout); - BIT_PTR_ADV(next); + PRED_BIT_PTR_SET(sout, PRED_BIT_PTR_GET(next)); + PRED_BIT_PTR_ADV(sout); + PRED_BIT_PTR_ADV(next); } for (i = 1; i < data->columns; i++) { for (j = 0; j < data->colors; j++) { - BIT_PTR_SET(sout, BIT_PTR_GET(next) - BIT_PTR_GET(this)); - BIT_PTR_ADV(sout); - BIT_PTR_ADV(next); - BIT_PTR_ADV(this); + PRED_BIT_PTR_SET(sout, PRED_BIT_PTR_GET(next) - PRED_BIT_PTR_GET(this)); + PRED_BIT_PTR_ADV(sout); + PRED_BIT_PTR_ADV(next); + PRED_BIT_PTR_ADV(this); } } } @@ -674,28 +677,28 @@ decode_row_sub_colorl8 (pdf_char_t* in, { int i; int j; - bit_ptr_t this; - bit_ptr_t next; - bit_ptr_t sin; - - bit_ptr_init (&this, cur, data->bits_per_component); - bit_ptr_init (&next, cur, data->bits_per_component); - bit_ptr_init (&sin, in, data->bits_per_component); + pred_bit_ptr_t this; + pred_bit_ptr_t next; + pred_bit_ptr_t sin; + + pred_bit_ptr_init (&this, cur, data->bits_per_component); + pred_bit_ptr_init (&next, cur, data->bits_per_component); + pred_bit_ptr_init (&sin, in, data->bits_per_component); for (j = 0; j < data->colors; j++) { - BIT_PTR_SET(next, BIT_PTR_GET(sin)); - BIT_PTR_ADV(next); - BIT_PTR_ADV(sin); + PRED_BIT_PTR_SET(next, PRED_BIT_PTR_GET(sin)); + PRED_BIT_PTR_ADV(next); + PRED_BIT_PTR_ADV(sin); } for (i = 1; i < data->columns; i++) { for (j = 0; j < data->colors; j++) { - BIT_PTR_SET(next, BIT_PTR_GET(sin) + BIT_PTR_GET(this)); - BIT_PTR_ADV(sin); - BIT_PTR_ADV(next); - BIT_PTR_ADV(this); + PRED_BIT_PTR_SET(next, PRED_BIT_PTR_GET(sin) + PRED_BIT_PTR_GET(this)); + PRED_BIT_PTR_ADV(sin); + PRED_BIT_PTR_ADV(next); + PRED_BIT_PTR_ADV(this); } } } diff -rup orig/libgnupdf/src/pdf_xref.h libgnupdf/src/pdf_xref.h --- orig/libgnupdf/src/pdf_xref.h 2007-07-07 23:35:42.000000000 +0200 +++ libgnupdf/src/pdf_xref.h 2007-09-03 20:51:40.000000000 +0200 @@ -38,7 +38,6 @@ #include - #endif /* pdf_xref.h */ /* End of pdf_xref.h */ Only in libgnupdf/torture: Makefile.in Only in libgnupdf/utils: Makefile.in diff -rup orig/libgnupdf/utils/pdf_filter.c libgnupdf/utils/pdf_filter.c --- orig/libgnupdf/utils/pdf_filter.c 2007-08-01 00:38:19.000000000 +0200 +++ libgnupdf/utils/pdf_filter.c 2007-09-05 18:02:25.000000000 +0200 @@ -19,6 +19,17 @@ #include /* + * Some default values for filters with arguments + */ + +#define DEF_LZW_EARLY_CHANGE PDF_FALSE +#define DEF_PRED_ENC_TYPE PDF_STM_F_PREDENC_TIFF_PREDICTOR_2 +#define DEF_PRED_DEC_TYPE PDF_STM_F_PREDDEC_TIFF_PREDICTOR_2 +#define DEF_PRED_COLORS 3 +#define DEF_PRED_BPC 8 +#define DEF_PRED_COLUMS 32 + +/* * Command line options management */ @@ -32,6 +43,7 @@ static struct option GNU_longOptions[] = {"ahexenc", no_argument, NULL, ASCIIHEXENC_FILTER_ARG}, {"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}, #ifdef HAVE_LIBZ {"flatedec", no_argument, NULL, FLATEDEC_FILTER_ARG}, @@ -45,14 +57,12 @@ static struct option GNU_longOptions[] = {"jxpdec", no_argument, NULL, JXPDEC_FILTER_ARG}, {"predenc", no_argument, NULL, PREDENC_FILTER_ARG}, {"preddec", no_argument, NULL, PREDDEC_FILTER_ARG}, - {"tiff", no_argument, NULL, TIFF_ARG}, - {"pngsub", no_argument, NULL, PNG_SUB_ARG}, - {"pngup", no_argument, NULL, PNG_UP_ARG}, - {"pngaverage", no_argument, NULL, PNG_AVERAGE_ARG}, - {"pngpaeth", no_argument, NULL, PNG_PAETH_ARG}, - {"colors", required_argument, NULL, COLORS_ARG}, - {"bpc", required_argument, NULL, BPC_ARG}, - {"columns", required_argument, NULL, COLUMNS_ARG}, + {"lzw-earlychange", no_argument, NULL, LZW_EARLY_CHANGE_ARG}, + {"predenc-type", required_argument, NULL, PREDENC_TYPE_ARG}, + {"preddec-type", required_argument, NULL, PREDDEC_TYPE_ARG}, + {"pred-colors", required_argument, NULL, PRED_COLORS_ARG}, + {"pred-bpc", required_argument, NULL, PRED_BPC_ARG}, + {"pred-columns", required_argument, NULL, PRED_COLUMNS_ARG}, {NULL, 0, NULL, 0} }; @@ -69,10 +79,11 @@ available filters\n\ --ahexenc use the ASCII Hex encoder filter\n\ --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" #ifdef HAVE_LIBZ -" --flatedec use the Flate decoder filter\n" -" --flateenc use the Flate encoder filter\n" +" --flatedec use the Flate decoder filter\n\ + --flateenc use the Flate encoder filter\n" #endif /* HAVE_LIBZ */ " --rldec use the Run Length decoder filter\n\ --rlenc use the Run Length encoder filter\n\ @@ -85,19 +96,38 @@ available filters\n\ --help print a help message and exit\n\ --usage print a usage message and exit\n\ --version show pdf_filter version and exit\n\ -encoding/decoding predictor filter arguments\n\ - --tiff use the TIFF predictor\n\ - --pngsub use the PNG sub predictor\n\ - --pngup use the PNG up predictor\n\ - --pngaverage use the PNG average predictor\n\ - --pngpaeth use the PNG paeth predictor\n\ - --colors=NUM number of color components per sample\n\ - --bpc=NUM bits per color component\n\ - --columns=NUM number of samples per row\n\ +\nfilter properties\n\ + --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\ "; char *pdf_filter_help_msg = ""; +typedef struct filter_args_s +{ + int lzw_early_change; + int pred_enc_type; + int pred_dec_type; + int pred_colors; + int pred_bpc; + int pred_columns; +} filter_args_t; + +static void +filter_args_init(filter_args_t* a) +{ + a->lzw_early_change = DEF_LZW_EARLY_CHANGE; + a->pred_enc_type = DEF_PRED_ENC_TYPE; + a->pred_dec_type = DEF_PRED_DEC_TYPE; + a->pred_colors = DEF_PRED_COLORS; + a->pred_bpc = DEF_PRED_BPC; + a->pred_columns = DEF_PRED_COLUMS; +} + int main (int argc, char *argv[]) { @@ -108,7 +138,7 @@ main (int argc, char *argv[]) char *line; unsigned char *output_buffer; int ret; - struct predictor_args_s pred_args; + filter_args_t args; /* Initialization */ input = pdf_create_mem_stm (0, /* Initial 0 length */ @@ -116,9 +146,7 @@ main (int argc, char *argv[]) 0, /* Init character */ PDF_TRUE); /* Auto-resize when necessary */ - pred_args.colors_p = PDF_FALSE; - pred_args.bpc_p = PDF_FALSE; - pred_args.columns_p = PDF_FALSE; + filter_args_init(&args); /* Manage command line arguments */ while ((ret = getopt_long (argc, @@ -130,6 +158,7 @@ main (int argc, char *argv[]) c = ret; switch (c) { + /* COMMON ARGUMENTS */ case HELP_ARG: { fprintf (stdout, "%s\n", pdf_filter_usage_msg); @@ -142,6 +171,7 @@ main (int argc, char *argv[]) exit (0); break; } + /* FILTER INSTALLERS */ case NULL_FILTER_ARG: { pdf_stm_install_null_filter (input, @@ -172,8 +202,18 @@ main (int argc, char *argv[]) PDF_STM_FILTER_READ); break; } + case LZWENC_FILTER_ARG: + { + pdf_stm_install_lzwenc_filter (input, + PDF_STM_FILTER_READ, + args.lzw_early_change); + break; + } case LZWDEC_FILTER_ARG: { + pdf_stm_install_lzwdec_filter (input, + PDF_STM_FILTER_READ, + args.lzw_early_change); break; } #ifdef HAVE_LIBZ @@ -222,19 +262,55 @@ main (int argc, char *argv[]) { pdf_stm_install_predenc_filter (input, PDF_STM_FILTER_READ, - PDF_STM_F_PREDENC_TIFF_PREDICTOR_2, - 1, 16, 2); + args.pred_enc_type, + args.pred_colors, + args.pred_bpc, + args.pred_columns); break; } case PREDDEC_FILTER_ARG: { pdf_stm_install_preddec_filter (input, PDF_STM_FILTER_READ, - PDF_STM_F_PREDDEC_TIFF_PREDICTOR_2, - 1, 16, 2); - break; - } - case '?': + args.pred_dec_type, + args.pred_colors, + args.pred_bpc, + args.pred_columns); + break; + } + /* FILTER OPTIONS: */ + case PREDDEC_TYPE_ARG: + { + args.pred_dec_type = atoi(optarg); + break; + } + case PREDENC_TYPE_ARG: + { + args.pred_enc_type = atoi(optarg); + break; + } + case PRED_COLORS_ARG: + { + args.pred_colors = atoi(optarg); + break; + } + case PRED_BPC_ARG: + { + args.pred_bpc = atoi(optarg); + break; + } + case PRED_COLUMNS_ARG: + { + args.pred_columns = atoi(optarg); + break; + } + case LZW_EARLY_CHANGE_ARG: + { + args.lzw_early_change = !args.lzw_early_change; + break; + } + /* ERROR: */ + case '?': { /* Error, usage and exit */ fprintf (stdout, "%s\n", pdf_filter_usage_msg); diff -rup orig/libgnupdf/utils/pdf_filter.h libgnupdf/utils/pdf_filter.h --- orig/libgnupdf/utils/pdf_filter.h 2007-08-01 00:38:19.000000000 +0200 +++ libgnupdf/utils/pdf_filter.h 2007-09-05 17:38:09.000000000 +0200 @@ -26,6 +26,7 @@ enum ASCIIHEXENC_FILTER_ARG, ASCII85DEC_FILTER_ARG, ASCII85ENC_FILTER_ARG, + LZWENC_FILTER_ARG, LZWDEC_FILTER_ARG, FLATEDEC_FILTER_ARG, FLATEENC_FILTER_ARG, @@ -35,26 +36,14 @@ enum JBIG2DEC_FILTER_ARG, DCTDEC_FILTER_ARG, JXPDEC_FILTER_ARG, + LZW_EARLY_CHANGE_ARG, PREDENC_FILTER_ARG, PREDDEC_FILTER_ARG, - TIFF_ARG, - PNG_SUB_ARG, - PNG_UP_ARG, - PNG_AVERAGE_ARG, - PNG_PAETH_ARG, - COLORS_ARG, - BPC_ARG, - COLUMNS_ARG -}; - -struct predictor_args_s -{ - int colors; - int colors_p; - int bpc; - int bpc_p; - int columns; - int columns_p; + PREDENC_TYPE_ARG, + PREDDEC_TYPE_ARG, + PRED_COLORS_ARG, + PRED_BPC_ARG, + PRED_COLUMNS_ARG }; #endif /* pdf_filter.h */