# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: address@hidden
# mxam0fl6yecepj50
# target_branch: bzr://bzr.sv.gnu.org/pdf/libgnupdf/trunk/
# testament_sha1: d930da392f37564acf022818d69798cad02a2e19
# timestamp: 2011-08-01 12:14:04 +0200
# base_revision_id: address@hidden
#
# Begin patch
=== modified file 'AUTHORS'
--- AUTHORS 2011-05-21 10:25:50 +0000
+++ AUTHORS 2011-07-30 21:08:22 +0000
@@ -33,6 +33,8 @@
Franck Lesage: changed pdf-hash-helper.c pdf-hash-helper.h gnupdf.texi
+Georg Gottleuber: changed pdf-filter.c pdf-stm-f-pred.c pdf-stm-f-pred.h
+
Gerardo E. Gidoni: changed gnupdf.texi pdf-stm-read.c gnupdf-tsd.texi
pdf-stm-write.c configure.ac pdf-filter.c pdf-stm-f-flate.h
pdf-stm-f-rl.c check-api-doc-consistency.pl
=== modified file 'ChangeLog'
--- ChangeLog 2011-07-07 16:01:46 +0000
+++ ChangeLog 2011-07-30 21:08:22 +0000
@@ -1,3 +1,15 @@
+2011-07-30 Georg Gottleuber
+
+ base,stm: adapted predictor filter to new stm api
+ * src/base/pdf-stm-f-pred.h: adapted to new stm api
+ * src/base/pdf-stm-f-pred.h: adapted to new stm api
+ * utils/pdf-filter.c: added support for predictor filter
+
+2011-07-30 Georg Gottleuber
+
+ utils: fix arg evaluation of pdf-filter
+ * utils/pdf-filter.c
+
2011-07-07 Aleksander Morgado
base,hash: cast to long all 32bit integers before packing them in a ptr.
=== modified file 'src/Makefile.am'
--- src/Makefile.am 2011-07-07 14:44:28 +0000
+++ src/Makefile.am 2011-07-30 21:08:22 +0000
@@ -58,7 +58,8 @@
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-lzw.h base/pdf-stm-f-lzw.c \
- base/pdf-stm-f-a85.h base/pdf-stm-f-a85.c
+ base/pdf-stm-f-a85.h base/pdf-stm-f-a85.c \
+ base/pdf-stm-f-pred.h base/pdf-stm-f-pred.c
if ZLIB
STM_MODULE_SOURCES += base/pdf-stm-f-flate.c base/pdf-stm-f-flate.h
=== modified file 'src/base/pdf-stm-f-pred.c'
--- src/base/pdf-stm-f-pred.c 2011-02-23 21:18:20 +0000
+++ src/base/pdf-stm-f-pred.c 2011-07-30 21:08:22 +0000
@@ -7,7 +7,7 @@
*
*/
-/* Copyright (C) 2007, 2008 Free Software Foundation, Inc. */
+/* Copyright (C) 2007-2011 Free Software Foundation, Inc. */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,6 +31,94 @@
#include
#include
+#include
+
+/* Define predictor encoder */
+PDF_STM_FILTER_DEFINE (pdf_stm_f_predenc_get,
+ stm_f_pred_init,
+ stm_f_predenc_apply,
+ stm_f_pred_deinit);
+
+/* Define predictor decoder */
+PDF_STM_FILTER_DEFINE (pdf_stm_f_preddec_get,
+ stm_f_pred_init,
+ stm_f_preddec_apply,
+ stm_f_pred_deinit);
+
+#define PRED_PARAM_PREDICTOR "Predictor"
+#define PRED_PARAM_COLORS "Colors"
+#define PRED_PARAM_BPC "BitsPerComponent"
+#define PRED_PARAM_COLUMNS "Columns"
+
+/* prediction modes */
+typedef enum
+{
+ PDF_STM_F_PREDENC_NO_PREDICTION = 1,
+ PDF_STM_F_PREDENC_TIFF_PREDICTOR_2 = 2,
+ PDF_STM_F_PREDENC_PNG_NONE_ALL_ROWS = 10,
+ PDF_STM_F_PREDENC_PNG_SUB_ALL_ROWS = 11,
+ PDF_STM_F_PREDENC_PNG_UP_ALL_ROWS = 12,
+ PDF_STM_F_PREDENC_PNG_AVERAGE_ALL_ROWS = 13,
+ PDF_STM_F_PREDENC_PNG_PAETH_ALL_ROWS = 14,
+ PDF_STM_F_PREDENC_PNG_OPTIMUM = 15
+} pdf_stm_f_predenc_method_t;
+
+typedef enum
+{
+ PDF_STM_F_PREDDEC_NO_PREDICTION = 1,
+ PDF_STM_F_PREDDEC_TIFF_PREDICTOR_2 = 2,
+ PDF_STM_F_PREDDEC_PNG = 3
+} pdf_stm_f_preddec_type_t;
+
+typedef enum
+{
+ PDF_STM_F_PREDDEC_PNG_NONE = 10,
+ PDF_STM_F_PREDDEC_PNG_SUB = 11,
+ PDF_STM_F_PREDDEC_PNG_UP = 12,
+ PDF_STM_F_PREDDEC_PNG_AVERAGE = 13,
+ PDF_STM_F_PREDDEC_PNG_PAETH = 14
+} pdf_stm_f_predec_png_type_t;
+
+
+/* END PUBLIC */
+
+/* Configuration structure */
+
+/* Private state */
+
+typedef struct pdf_stm_f_pred_s
+{
+ int predictor; /* A code that selects the predictor algorithm. If
+ the value of this entry is 1, the filter assumes
+ that the normal algorithm was used to encode the
+ data, without prediction. If the value is greater
+ than 1, the filter assumes that the data was
+ differenced before being encoded, and `predictor'
+ selects the predictor algorithm */
+
+ /* The following parameters are only useful when `predictor' > 1 */
+ pdf_size_t colors; /* Number of interleaved color components
+ per sample. Valid values are 1 or
+ greater. Default value: 1 */
+ pdf_size_t bits_per_component; /* The number of bits used to represent
+ each color component in a sample. Valid
+ values are 1, 2, 4, 8 and 16. Default
+ value: 1 */
+ pdf_size_t columns; /* The number of samples in each
+ row. Default value: 1 */
+
+ pdf_size_t scanline_len; /* will be calculated from params */
+
+ /* previous and current buffers for scanlines (rows)
+ encoder uses prev_row_buf for last input row to the filter
+ decoder uses prev_row_buf for last filtered output row */
+ pdf_buffer_t *prev_row_buf;
+ pdf_buffer_t *curr_row_buf;
+
+ /* buffer for output scanline (already filtered) */
+ pdf_buffer_t *out_row_buf;
+} pdf_stm_f_pred_t;
+
#define PNG_ENC_PREDICTOR_P(pred) \
((pred) == PDF_STM_F_PREDENC_PNG_NONE_ALL_ROWS || \
@@ -40,6 +128,14 @@
(pred) == PDF_STM_F_PREDENC_PNG_PAETH_ALL_ROWS || \
(pred) == PDF_STM_F_PREDENC_PNG_OPTIMUM)
+#define PNG_DEC_PREDICTOR_P(pred) \
+ ((pred) == PDF_STM_F_PREDDEC_PNG || \
+ (pred) == PDF_STM_F_PREDDEC_PNG_NONE || \
+ (pred) == PDF_STM_F_PREDDEC_PNG_SUB || \
+ (pred) == PDF_STM_F_PREDDEC_PNG_UP || \
+ (pred) == PDF_STM_F_PREDDEC_PNG_AVERAGE || \
+ (pred) == PDF_STM_F_PREDDEC_PNG_PAETH)
+
/*
* 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
@@ -70,10 +166,10 @@
bp->mask = ~bp->mask;
}
-#define PRED_BIT_PTR_ADV(bp) \
- if ((bp).offset > 0) \
+#define PRED_BIT_PTR_ADV(bp) \
+ if ((bp).offset > 0) \
{ \
- (bp).offset -= (bp).block_size; \
+ (bp).offset -= (bp).block_size; \
} \
else \
{ \
@@ -81,63 +177,178 @@
(bp).offset = 8 - (bp).block_size; \
}
-#define PRED_BIT_PTR_GET(bp) \
+#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))
+#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,
- void *conf_data)
+static pdf_bool_t
+stm_f_pred_init (const pdf_hash_t *params,
+ void **state,
+ pdf_error_t **error)
{
- int actual_len;
-
- pdf_stm_f_pred_data_t *data;
- pdf_stm_f_pred_conf_t conf;
-
- data = (pdf_stm_f_pred_data_t *) filter_data;
- conf = (pdf_stm_f_pred_conf_t) conf_data;
-
- /* Create the private data storage */
- *data =
- (pdf_stm_f_pred_data_t) pdf_alloc (sizeof(struct pdf_stm_f_pred_data_s));
-
- (*data)->mode = conf->mode;
- (*data)->predictor = conf->predictor;
- (*data)->colors = conf->colors;
- (*data)->bits_per_component = conf->bits_per_component;
- (*data)->columns = conf->columns;
-
+ pdf_size_t actual_len;
+ pdf_stm_f_pred_t* filter_state;
+
+ /* Predictor decides if we need more paramters; so check it first */
+ if (!params || !pdf_hash_key_p (params, PRED_PARAM_PREDICTOR))
+ {
+ pdf_set_error (error,
+ PDF_EDOMAIN_BASE_STM,
+ PDF_EBADDATA,
+ "cannot initialize predictor encoder/decoder: "
+ "parameter '"PRED_PARAM_PREDICTOR"' missing");
+ return PDF_FALSE;
+ }
+
+ /* We demand all parameters if predictor > 1 */
+ if (pdf_hash_get_size (params, PRED_PARAM_PREDICTOR) > 1)
+ {
+ if (!pdf_hash_key_p (params, PRED_PARAM_COLORS) ||
+ !pdf_hash_key_p (params, PRED_PARAM_BPC) ||
+ !pdf_hash_key_p (params, PRED_PARAM_COLUMNS))
+ {
+ pdf_set_error (error,
+ PDF_EDOMAIN_BASE_STM,
+ PDF_EBADDATA,
+ "cannot initialize predictor encoder/decoder: "
+ "parameters missing ('"PRED_PARAM_COLORS"': %s, "
+ "'"PRED_PARAM_BPC"': %s, '"PRED_PARAM_COLUMNS"': %s)",
+ ((params && pdf_hash_key_p (params, PRED_PARAM_COLORS)) ?
+ "available" : "missing"),
+ ((params && pdf_hash_key_p (params, PRED_PARAM_BPC)) ?
+ "available" : "missing"),
+ ((params && pdf_hash_key_p (params, PRED_PARAM_COLUMNS)) ?
+ "available" : "missing"));
+ return PDF_FALSE;
+ }
+ }
+
+ /* Create the private filter_state storage */
+ filter_state = pdf_alloc (sizeof (struct pdf_stm_f_pred_s));
+ if (!filter_state)
+ {
+ pdf_set_error (error,
+ PDF_EDOMAIN_BASE_STM,
+ PDF_ENOMEM,
+ "cannot create predictor encoder/decoder internal state: "
+ "couldn't allocate %lu bytes",
+ (unsigned long) sizeof (pdf_stm_f_pred_t));
+ return PDF_FALSE;
+ }
+
+ filter_state->predictor = pdf_hash_get_size (params, PRED_PARAM_PREDICTOR);
+ filter_state->colors = pdf_hash_get_size (params, PRED_PARAM_COLORS);
+ filter_state->bits_per_component = pdf_hash_get_size (params, PRED_PARAM_BPC);
+ filter_state->columns = pdf_hash_get_size (params, PRED_PARAM_COLUMNS);
+
+ /* as no parameters for predictor 1 (NO_PREDICTION) is needed */
+ if (filter_state->predictor == PDF_STM_F_PREDENC_NO_PREDICTION)
+ {
+ /* set default values */
+ filter_state->colors = 1;
+ filter_state->bits_per_component = 1;
+ filter_state->columns = 1;
+ }
+ /* else wise check for bad parameter values */
+ else
+ {
+ if (filter_state->colors < 1
+ || filter_state->columns < 1
+ || filter_state->bits_per_component < 1)
+ {
+ pdf_set_error (error,
+ PDF_EDOMAIN_BASE_STM,
+ PDF_EBADDATA,
+ "cannot initialize predictor encoder/decoder: "
+ "bad parameter values ('"PRED_PARAM_COLORS"': %s, "
+ "'"PRED_PARAM_BPC"': %s, '"PRED_PARAM_COLUMNS"': %s)",
+ ((filter_state->colors < 1) ?
+ "bad" : "ok"),
+ ((filter_state->bits_per_component < 1) ?
+ "bad" : "ok"),
+ ((filter_state->columns < 1) ?
+ "bad" : "ok"));
+ return PDF_FALSE;
+ }
+ }
+
/* We need the number of full bytes that each row has. As defined in the
* PNG standard we can assume that if greater than 8 the bits per component
* is multiplier of eight. */
- actual_len = conf->columns * conf->colors * conf->bits_per_component;
- (*data)->scanline_len = (actual_len >> 3) + (actual_len & 7);
-
- return PDF_OK;
+ actual_len = filter_state->columns * filter_state->colors *
+ filter_state->bits_per_component;
+ filter_state->scanline_len = (actual_len >> 3) + (actual_len & 7);
+
+ /* one extra byte for PNG predictor */
+ filter_state->prev_row_buf = pdf_buffer_new (filter_state->scanline_len + 1,
+ error);
+ if (!(filter_state->prev_row_buf))
+ {
+ pdf_set_error (error,
+ PDF_EDOMAIN_BASE_STM,
+ PDF_ENOMEM,
+ "cannot create predictor encoder/decoder internal buffer: "
+ "couldn't allocate %lu bytes",
+ (unsigned long) filter_state->scanline_len);
+ return PDF_FALSE;
+ }
+
+ /* hint for further optimizing (if necessary): if scanlines are smaller than
+ in and out buffers, curr_row_buf and out_row_buf are not needed and two
+ memcpys per scanline can be omitted */
+ filter_state->curr_row_buf = pdf_buffer_new (filter_state->scanline_len + 1,
+ error);
+ if (!(filter_state->curr_row_buf))
+ {
+ pdf_set_error (error,
+ PDF_EDOMAIN_BASE_STM,
+ PDF_ENOMEM,
+ "cannot create predictor encoder/decoder internal buffer: "
+ "couldn't allocate %lu bytes",
+ (unsigned long) filter_state->scanline_len);
+ return PDF_FALSE;
+ }
+ filter_state->out_row_buf = pdf_buffer_new (filter_state->scanline_len + 1,
+ error);
+ if (!(filter_state->out_row_buf))
+ {
+ pdf_set_error (error,
+ PDF_EDOMAIN_BASE_STM,
+ PDF_ENOMEM,
+ "cannot create predictor encoder/decoder internal buffer: "
+ "couldn't allocate %lu bytes",
+ (unsigned long) filter_state->scanline_len + 1);
+ return PDF_FALSE;
+ }
+
+ *state = filter_state;
+ return PDF_TRUE;
}
+
static void
encode_row_none(pdf_char_t* cur,
pdf_char_t* prev,
pdf_char_t* out,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- memcpy(out, cur, data->scanline_len);
+ memcpy(out, cur, state->scanline_len);
}
static void
encode_row_sub(pdf_char_t* cur,
pdf_char_t* prev,
pdf_char_t* out,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- int i;
+ pdf_size_t i;
*out++ = *cur++;
- for (i = 1; i < data->scanline_len; i++)
+ for (i = 1; i < state->scanline_len; i++)
{
- *out = *cur - *(cur-1);
+ *out++ = *cur - *(cur-1);
cur++;
}
}
@@ -146,34 +357,34 @@
encode_row_up(pdf_char_t* cur,
pdf_char_t* prev,
pdf_char_t* out,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- int i;
+ pdf_size_t i;
if (prev != NULL)
{
- for (i = 0; i < data->scanline_len; i++)
+ for (i = 0; i < state->scanline_len; i++)
{
*out++ = *cur++ - *prev++;
}
- }
+ }
else
{
- memcpy(out, cur, data->scanline_len);
+ memcpy(out, cur, state->scanline_len);
}
}
static void
-encode_row_average(pdf_char_t* cur,
- pdf_char_t* prev,
+encode_row_average(pdf_char_t* cur,
+ pdf_char_t* prev,
pdf_char_t* out,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- int i;
- if (prev != NULL)
+ pdf_size_t i;
+ if (prev != NULL)
{
*out++ = *cur++ - (*prev++ >> 1);
- for (i = 1; i < data->scanline_len; i++)
+ for (i = 1; i < state->scanline_len; i++)
{
*out++ = *cur - (pdf_char_t)(((int)*(cur-1) + (int)*prev) >> 1);
cur++;
@@ -184,7 +395,7 @@
{
*out++ = *cur++;
- for (i = 1; i < data->scanline_len; i++)
+ for (i = 1; i < state->scanline_len; i++)
{
*out++ = *cur - (*(cur-1) >> 1);
cur++;
@@ -196,9 +407,9 @@
encode_row_paeth (pdf_char_t* cur,
pdf_char_t* prev,
pdf_char_t* out,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- int i;
+ pdf_size_t i;
int p;
int pa;
int pb;
@@ -208,7 +419,7 @@
{
*out++ = *cur++ - *prev++;
- for (i = 0; i < data->scanline_len; i++)
+ for (i = 0; i < state->scanline_len; i++)
{
p = *(cur-1) + *(prev) - *(prev-1);
pa = abs(p - *(cur-1));
@@ -239,9 +450,9 @@
{
*out++ = *cur++;
- for (i = 1; i < data->scanline_len; i++)
+ for (i = 1; i < state->scanline_len; i++)
{
- *out = *cur - *(cur-1);
+ *out++ = *cur - *(cur-1);
cur++;
}
}
@@ -251,10 +462,10 @@
encode_row_sub_color16 (pdf_char_t* cur,
pdf_char_t* prev,
pdf_char_t* out,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- int i;
- int j;
+ pdf_size_t i;
+ pdf_size_t j;
unsigned short *this;
unsigned short *next;
@@ -264,14 +475,14 @@
next = (unsigned short*) cur;
sout = (unsigned short*) out;
- for (j = 0; j < data->colors; j++)
+ for (j = 0; j < state->colors; j++)
{
*sout++ = *next++;
}
- for (i = 1; i < data->columns; i++)
+ for (i = 1; i < state->columns; i++)
{
- for (j = 0; j < data->colors; j++)
+ for (j = 0; j < state->colors; j++)
{
*sout++ = *next++ - *this++;
}
@@ -282,10 +493,10 @@
encode_row_sub_color8 (pdf_char_t* cur,
pdf_char_t* prev,
pdf_char_t* out,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- int i;
- int j;
+ pdf_size_t i;
+ pdf_size_t j;
pdf_char_t *this;
pdf_char_t *next;
pdf_char_t *sout;
@@ -294,13 +505,13 @@
next = cur;
sout = out;
- for (j = 0; j < data->colors; j++)
+ for (j = 0; j < state->colors; j++)
{
*sout++ = *next++;
}
- for (i = 1; i < data->columns; i++)
+ for (i = 1; i < state->columns; i++)
{
- for (j = 0; j < data->colors; j++)
+ for (j = 0; j < state->colors; j++)
{
*sout++ = *next++ - *this++;
}
@@ -311,29 +522,30 @@
encode_row_sub_colorl8 (pdf_char_t *cur,
pdf_char_t *prev,
pdf_char_t *out,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- int i;
- int j;
+ pdf_size_t i;
+ pdf_size_t j;
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);
+ pred_bit_ptr_init (&this, cur, state->bits_per_component);
+ pred_bit_ptr_init (&next, cur, state->bits_per_component);
+ pred_bit_ptr_init (&sout, out, state->bits_per_component);
- for (j = 0; j < data->colors; j++)
+ for (j = 0; j < state->colors; j++)
{
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 (i = 1; i < state->columns; i++)
{
- for (j = 0; j < data->colors; j++)
+ for (j = 0; j < state->colors; j++)
{
- PRED_BIT_PTR_SET(sout, PRED_BIT_PTR_GET(next) - PRED_BIT_PTR_GET(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);
@@ -342,42 +554,48 @@
}
static int
-encode_row (pdf_char_t *cur,
- pdf_char_t *prev,
+encode_row (pdf_char_t *cur,
+ pdf_char_t *prev,
pdf_char_t *out,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state,
+ pdf_error_t **error)
{
- switch (data->predictor)
+ switch (state->predictor)
{
case PDF_STM_F_PREDENC_NO_PREDICTION:
case PDF_STM_F_PREDENC_PNG_NONE_ALL_ROWS:
{
- encode_row_none(cur, prev, out, data);
+ encode_row_none(cur, prev, out, state);
break;
}
case PDF_STM_F_PREDENC_TIFF_PREDICTOR_2:
{
- switch (data->bits_per_component)
+ switch (state->bits_per_component)
{
case 16:
{
- encode_row_sub_color16(cur, prev, out, data);
+ encode_row_sub_color16(cur, prev, out, state);
break;
}
case 8:
{
- encode_row_sub_color8(cur, prev, out, data);
+ encode_row_sub_color8(cur, prev, out, state);
break;
}
case 4: case 2: case 1:
{
- encode_row_sub_colorl8(cur, prev, out, data);
+ encode_row_sub_colorl8(cur, prev, out, state);
break;
}
default:
{
+ pdf_set_error (error,
+ PDF_EDOMAIN_BASE_STM,
+ PDF_EBADDATA,
+ "bad bits_per_component value: "
+ "expected 1, 2, 4, 8, 16, got %d",
+ (state->bits_per_component));
return PDF_ERROR;
- /* Make stupid compilers happy */
break;
}
}
@@ -386,28 +604,33 @@
}
case PDF_STM_F_PREDENC_PNG_SUB_ALL_ROWS:
{
- encode_row_sub (cur, prev, out, data);
+ encode_row_sub (cur, prev, out, state);
break;
}
case PDF_STM_F_PREDENC_PNG_UP_ALL_ROWS:
{
- encode_row_up(cur, prev, out, data);
+ encode_row_up(cur, prev, out, state);
break;
}
case PDF_STM_F_PREDENC_PNG_AVERAGE_ALL_ROWS:
{
- encode_row_average(cur, prev, out, data);
+ encode_row_average(cur, prev, out, state);
break;
}
case PDF_STM_F_PREDENC_PNG_PAETH_ALL_ROWS:
{
- encode_row_paeth(cur, prev, out, data);
+ encode_row_paeth(cur, prev, out, state);
break;
}
default:
{
+ pdf_set_error (error,
+ PDF_EDOMAIN_BASE_STM,
+ PDF_EBADDATA,
+ "bad predictor value in input data: "
+ "expected 1, 2, 10, 11, 12, 13, 14 got %d",
+ (state->predictor));
return PDF_ERROR;
- /* Make stupid compilers happy */
break;
}
}
@@ -415,85 +638,26 @@
return PDF_OK;
}
-
-static int
-pdf_stm_f_pred_encode (pdf_stm_f_pred_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 *curr;
- pdf_char_t *prev;
- pdf_char_t *buf;
-
- int is_png_predictor = PNG_ENC_PREDICTOR_P(data->predictor);
- int i;
-
- curr = in;
- prev = NULL;
- buf = NULL;
-
- if (in_size % data->scanline_len != 0)
- {
- /* Not all rows al full. */
- return PDF_ERROR;
- }
-
- *out_size = is_png_predictor ? in_size + in_size/data->scanline_len : in_size;
-
- *out = (pdf_char_t *) pdf_alloc (*out_size);
- if (*out == NULL)
- {
- *out_size = 0;
- return PDF_ERROR;
- }
-
- buf = *out;
-
- for (i = 0; i < in_size; i += data->scanline_len)
- {
- if (is_png_predictor)
- {
- *buf++ = data->predictor;
- }
-
- if (encode_row(curr, prev, buf, data) == PDF_ERROR)
- {
- pdf_dealloc (*out);
- *out = NULL;
- *out_size = 0;
- return PDF_ERROR;
- }
-
- prev = curr;
- curr += data->scanline_len;
- buf += data->scanline_len;
- }
-
- return PDF_OK;
-}
-
static void
decode_row_none (pdf_char_t* in,
pdf_char_t* cur,
pdf_char_t* prev,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- memcpy (cur, in, data->scanline_len);
+ memcpy (cur, in, state->scanline_len);
}
static void
decode_row_sub (pdf_char_t* in,
pdf_char_t* cur,
pdf_char_t* prev,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- int i;
+ pdf_size_t i;
*cur++ = *in++;
- for (i = 1; i < data->scanline_len; i++)
+ for (i = 1; i < state->scanline_len; i++)
{
*cur = *in++ + *(cur-1);
cur++;
@@ -504,13 +668,13 @@
decode_row_up (pdf_char_t* in,
pdf_char_t* cur,
pdf_char_t* prev,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- int i;
+ pdf_size_t i;
if (prev != NULL)
{
- for (i = 0; i < data->scanline_len; i++)
+ for (i = 0; i < state->scanline_len; i++)
{
*cur++ = *in++ + *prev++;
}
@@ -518,7 +682,7 @@
}
else
{
- memcpy (cur, in, data->scanline_len);
+ memcpy (cur, in, state->scanline_len);
}
}
@@ -526,15 +690,15 @@
decode_row_average (pdf_char_t* in,
pdf_char_t* cur,
pdf_char_t* prev,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- int i;
+ pdf_size_t i;
if (prev != NULL)
{
*cur++ = *in++ + (*prev++ >> 1);
-
- for (i = 1; i < data->scanline_len; i++)
+
+ for (i = 1; i < state->scanline_len; i++)
{
*cur = *in++ + (pdf_char_t)(((int)*(cur-1) + (int)*prev) >> 1);
cur++;
@@ -545,7 +709,7 @@
{
*cur++ = *in++;
- for (i = 1; i < data->scanline_len; i++)
+ for (i = 1; i < state->scanline_len; i++)
{
*cur = *in++ + (*(cur-1) >> 1);
cur++;
@@ -557,19 +721,19 @@
decode_row_paeth (pdf_char_t* in,
pdf_char_t* cur,
pdf_char_t* prev,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
int p;
int pa;
int pb;
int pc;
- int i;
+ pdf_size_t i;
if (prev != NULL)
{
*cur++ = *in++ + *prev++;
- for (i = 0; i < data->scanline_len; i++)
+ for (i = 0; i < state->scanline_len; i++)
{
p = *(cur-1) + *(prev) - *(prev-1);
pa = abs(p - *(cur-1));
@@ -601,7 +765,7 @@
{
*cur++ = *in++;
- for (i = 1; i < data->scanline_len; i++)
+ for (i = 1; i < state->scanline_len; i++)
{
*cur = *in++ + *(cur-1);
cur++;
@@ -611,10 +775,10 @@
static void
decode_row_sub_color16 (pdf_char_t* in, pdf_char_t* cur, pdf_char_t* prev,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- int i;
- int j;
+ pdf_size_t i;
+ pdf_size_t j;
unsigned short* this;
unsigned short* next;
unsigned short* sin;
@@ -623,13 +787,13 @@
next = (unsigned short*) cur;
sin = (unsigned short*) in;
- for (j = 0; j < data->colors; j++)
+ for (j = 0; j < state->colors; j++)
{
*next++ = *sin++;
}
- for (i = 1; i < data->columns; i++)
+ for (i = 1; i < state->columns; i++)
{
- for (j = 0; j < data->colors; j++)
+ for (j = 0; j < state->colors; j++)
{
*next++ = *sin++ + *this++;
}
@@ -640,10 +804,10 @@
decode_row_sub_color8 (pdf_char_t* in,
pdf_char_t* cur,
pdf_char_t* prev,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- int i;
- int j;
+ pdf_size_t i;
+ pdf_size_t j;
pdf_char_t *this;
pdf_char_t *next;
pdf_char_t *sin;
@@ -652,14 +816,14 @@
next = cur;
sin = in;
- for (j = 0; j < data->colors; j++)
+ for (j = 0; j < state->colors; j++)
{
*next++ = *sin++;
}
- for (i = 1; i < data->columns; i++)
+ for (i = 1; i < state->columns; i++)
{
- for (j = 0; j < data->colors; j++)
+ for (j = 0; j < state->colors; j++)
{
*next++ = *sin++ + *this++;
}
@@ -671,29 +835,30 @@
decode_row_sub_colorl8 (pdf_char_t* in,
pdf_char_t* cur,
pdf_char_t* prev,
- pdf_stm_f_pred_data_t data)
+ pdf_stm_f_pred_t* state)
{
- int i;
- int j;
+ pdf_size_t i;
+ pdf_size_t j;
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);
+ pred_bit_ptr_init (&this, cur, state->bits_per_component);
+ pred_bit_ptr_init (&next, cur, state->bits_per_component);
+ pred_bit_ptr_init (&sin, in, state->bits_per_component);
- for (j = 0; j < data->colors; j++)
+ for (j = 0; j < state->colors; j++)
{
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 (i = 1; i < state->columns; i++)
{
- for (j = 0; j < data->colors; j++)
+ for (j = 0; j < state->colors; j++)
{
- PRED_BIT_PTR_SET(next, PRED_BIT_PTR_GET(sin) + PRED_BIT_PTR_GET(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);
@@ -702,37 +867,44 @@
}
static int
-decode_row (pdf_char_t* in,
- pdf_char_t* cur,
+decode_row (pdf_char_t* in,
+ pdf_char_t* cur,
pdf_char_t* prev,
- pdf_stm_f_pred_data_t data,
- pdf_char_t predictor)
+ pdf_stm_f_pred_t* state,
+ pdf_error_t **error)
{
- switch (predictor)
+ switch (state->predictor)
{
case PDF_STM_F_PREDDEC_TIFF_PREDICTOR_2:
{
- switch(data->bits_per_component)
+ switch(state->bits_per_component)
{
case 16:
{
- decode_row_sub_color16(in, cur, prev, data);
+ decode_row_sub_color16(in, cur, prev, state);
break;
}
case 8:
{
- decode_row_sub_color8(in, cur, prev, data);
+ decode_row_sub_color8(in, cur, prev, state);
break;
}
case 4:
case 2:
case 1:
{
- decode_row_sub_colorl8(in, cur, prev, data);
+ decode_row_sub_colorl8(in, cur, prev, state);
break;
}
- default:
+ default:
{
+ pdf_set_error (error,
+ PDF_EDOMAIN_BASE_STM,
+ PDF_EBADDATA,
+ "bad bits_per_component value: "
+ "expected 16, 8, 4, 2, 1, got %d",
+ (state->bits_per_component));
+ return PDF_ERROR;
break;
}
}
@@ -741,129 +913,317 @@
case PDF_STM_F_PREDDEC_NO_PREDICTION:
case PDF_STM_F_PREDDEC_PNG_NONE:
{
- decode_row_none (in, cur, prev, data);
+ decode_row_none (in, cur, prev, state);
break;
}
case PDF_STM_F_PREDDEC_PNG_SUB:
{
- decode_row_sub (in, cur, prev, data);
+ decode_row_sub (in, cur, prev, state);
break;
}
case PDF_STM_F_PREDDEC_PNG_UP:
{
- decode_row_up (in, cur, prev, data);
+ decode_row_up (in, cur, prev, state);
break;
}
case PDF_STM_F_PREDDEC_PNG_AVERAGE:
{
- decode_row_average (in, cur, prev, data);
+ decode_row_average (in, cur, prev, state);
break;
}
case PDF_STM_F_PREDDEC_PNG_PAETH:
{
- decode_row_paeth (in, cur, prev, data);
- break;
- }
- default:
- {
- return PDF_ERROR;
- /* Make stupid compilers happy */
- break;
- }
- }
-
- return PDF_OK;
-}
-
-static int
-pdf_stm_f_pred_decode (pdf_stm_f_pred_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 *curr = NULL;
- pdf_char_t *prev = NULL;
- int is_png_predictor;
- int i;
- pdf_char_t predictor;
-
- curr = NULL;
- prev = NULL;
- is_png_predictor = data->predictor == PDF_STM_F_PREDDEC_PNG;
- predictor = data->predictor;
-
- if (is_png_predictor ?
- in_size * data->scanline_len % (data->scanline_len + 1) != 0 :
- in_size % data->scanline_len != 0 )
- {
- /* Not all rows al full. */
- return PDF_ERROR;
- }
-
- *out_size = is_png_predictor ? in_size * data->scanline_len / (data->scanline_len + 1) : in_size;
-
- if ((*out = (pdf_char_t *) pdf_alloc (*out_size)) == NULL)
- {
- *out_size = 0;
- return PDF_ERROR;
- }
-
- curr = *out;
- for (i = 0; i < in_size; i += data->scanline_len + is_png_predictor)
- {
- if (is_png_predictor)
- {
- predictor = *in++;
- }
-
- if (decode_row(in, curr, prev, data, predictor) == PDF_ERROR)
- {
- pdf_dealloc (*out);
- *out = NULL;
- *out_size = 0;
- return PDF_ERROR;
- }
-
- prev = curr;
- curr += data->scanline_len;
- in += data->scanline_len;
- }
-
- return PDF_OK;
-}
-
-int
-pdf_stm_f_pred_apply (void *filter_data,
- pdf_char_t *in, pdf_stm_pos_t in_size,
- pdf_char_t **out, pdf_stm_pos_t *out_size)
-{
- switch (((pdf_stm_f_pred_data_t)filter_data)->mode)
- {
- case PDF_STM_F_PRED_MODE_ENCODE:
- {
- return pdf_stm_f_pred_encode (filter_data, in, in_size, out, out_size);
- }
- case PDF_STM_F_PRED_MODE_DECODE:
- {
- return pdf_stm_f_pred_decode (filter_data, in, in_size, out, out_size);
- }
- default:
- {
- return PDF_ERROR;
- }
- }
-}
-
-int
-pdf_stm_f_pred_dealloc (void **filter_data)
-{
- pdf_stm_f_pred_data_t *data;
-
- data = (pdf_stm_f_pred_data_t *) filter_data;
- pdf_dealloc (*data);
-
- return PDF_OK;
+ decode_row_paeth (in, cur, prev, state);
+ break;
+ }
+ default:
+ {
+ pdf_set_error (error,
+ PDF_EDOMAIN_BASE_STM,
+ PDF_EBADDATA,
+ "bad predictor value for decode: "
+ "expected 1, 2, 10, 11, 12, 13, 14 got %d",
+ (state->predictor));
+ return PDF_ERROR;
+ break;
+ }
+ }
+
+ return PDF_OK;
+}
+
+static enum pdf_stm_filter_apply_status_e
+stm_f_predenc_apply (void *state,
+ pdf_buffer_t *in,
+ pdf_buffer_t *out,
+ pdf_bool_t finish,
+ pdf_error_t **error)
+{
+ pdf_stm_f_pred_t *fs = state; /* filter state */
+
+ pdf_bool_t is_png_predictor;
+ is_png_predictor = PNG_ENC_PREDICTOR_P(fs->predictor);
+
+ pdf_char_t *curr_row;
+ pdf_char_t *prev_row = NULL;
+ pdf_char_t *out_buf;
+
+ pdf_size_t in_size;
+ PDF_ASSERT (in->wp >= in->rp);
+
+ size_t tocpy;
+
+ /* copy all at once instead of copying each scanline for predictor 1;
+ this is needed because we may not know real scanline_len and therefor use
+ scanline_len = 1 which would be very slow */
+ if (fs->predictor == PDF_STM_F_PREDENC_NO_PREDICTION)
+ {
+ tocpy = PDF_MIN (out->size - out->wp, in->wp - in->rp);
+ memcpy(out->data + out->wp, in->data + in->rp, tocpy);
+ out->wp += tocpy;
+ in->rp += tocpy;
+ }
+
+ /* copy in->data to buffer and filter it */
+ do
+ {
+ in_size = in->wp - in->rp;
+ tocpy = PDF_MIN (fs->curr_row_buf->size - fs->curr_row_buf->wp - 1,
+ in_size);
+
+ memcpy (fs->curr_row_buf->data + fs->curr_row_buf->wp, in->data + in->rp,
+ tocpy);
+
+ fs->curr_row_buf->wp += tocpy;
+ in->rp += tocpy;
+
+ /* one scanline is in curr_row_buf ready for filtering */
+ if (fs->curr_row_buf->wp - fs->curr_row_buf->rp == fs->scanline_len)
+ {
+ /* check if out buffer has enough space left */
+ pdf_size_t left;
+ left = fs->out_row_buf->size - fs->out_row_buf->wp;
+ /* PNG predictor needs extra byte per row */
+ if (left >= fs->scanline_len + (is_png_predictor? 1 : 0))
+ {
+ /* write/read PNG predictor at first byte of a row */
+ if (is_png_predictor)
+ fs->out_row_buf->data[fs->out_row_buf->wp++] = fs->predictor;
+
+ curr_row = (pdf_char_t*) fs->curr_row_buf->data;
+ out_buf = (pdf_char_t*) fs->out_row_buf->data
+ + fs->out_row_buf->wp;
+
+ /* at first row encode_row expects prev_row to be NULL */
+ if (fs->prev_row_buf->wp == 0)
+ prev_row = NULL;
+ else
+ prev_row = (pdf_char_t*) fs->prev_row_buf->data;
+
+ if (encode_row (curr_row, prev_row, out_buf, fs, error)
+ == PDF_ERROR)
+ return PDF_STM_FILTER_APPLY_STATUS_ERROR;
+
+ fs->out_row_buf->wp += fs->scanline_len;
+
+ /* instead of copying curr to prev, swap addresses */
+ pdf_buffer_t *swap_tmp_buf = fs->prev_row_buf;
+ fs->prev_row_buf = fs->curr_row_buf;
+ fs->curr_row_buf = swap_tmp_buf;
+
+ pdf_buffer_rewind (fs->curr_row_buf);
+ }
+ }
+
+ /* out_row_buf has data that can be written to out buffer */
+ if (out->size - out->wp > 0 && !pdf_buffer_eob_p (fs->out_row_buf))
+ {
+ tocpy = PDF_MIN (fs->out_row_buf->wp - fs->out_row_buf->rp,
+ out->size - out->wp);
+
+ memcpy (out->data + out->wp,
+ fs->out_row_buf->data + fs->out_row_buf->rp,
+ tocpy);
+
+ out->wp += tocpy;
+ fs->out_row_buf->rp += tocpy;
+ }
+ if (pdf_buffer_eob_p (fs->out_row_buf))
+ {
+ pdf_buffer_rewind (fs->out_row_buf);
+ }
+
+ }
+ while (!pdf_buffer_eob_p (in) && !pdf_buffer_full_p (out));
+
+ /* if we do PNG prediction (is_png_predictor) and in->size == out->size
+ * it happens that out->data is full and we have not read all of in->data */
+ if (pdf_buffer_full_p (out) && !pdf_buffer_eob_p (in))
+ return PDF_STM_FILTER_APPLY_STATUS_NO_OUTPUT;
+
+ /* final call of this filter; empty out_row_buf */
+ if (finish && in->wp - in->rp < 1)
+ {
+ /* out_row_buf has data because out is full */
+ if (!pdf_buffer_eob_p (fs->out_row_buf))
+ return PDF_STM_FILTER_APPLY_STATUS_NO_OUTPUT;
+ /* input % scanline_len != 0 */
+ if (!pdf_buffer_eob_p (fs->curr_row_buf))
+ {
+ pdf_set_error (error,
+ PDF_EDOMAIN_BASE_STM,
+ PDF_EBADDATA,
+ "filtering with predictor encoder is incomplete: "
+ "out of data in the middle of a scanline "
+ "or wrong columns parameter detected");
+ return PDF_STM_FILTER_APPLY_STATUS_ERROR;
+ }
+ return PDF_STM_FILTER_APPLY_STATUS_EOF;
+ }
+
+ return PDF_STM_FILTER_APPLY_STATUS_NO_INPUT;
+}
+
+static enum pdf_stm_filter_apply_status_e
+stm_f_preddec_apply (void *state,
+ pdf_buffer_t *in,
+ pdf_buffer_t *out,
+ pdf_bool_t finish,
+ pdf_error_t **error)
+{
+ pdf_stm_f_pred_t *fs = state; /* filter state */
+
+ pdf_bool_t is_png_predictor;
+ is_png_predictor = PNG_DEC_PREDICTOR_P(fs->predictor);
+
+ pdf_char_t *curr_row;
+ pdf_char_t *prev_row = NULL;
+ pdf_char_t *out_buf;
+
+ pdf_size_t in_size;
+ PDF_ASSERT (in->wp >= in->rp);
+
+ size_t tocpy;
+
+ /* copy all at once instead of copying each scanline for predictor 1;
+ this is needed because we may not know real scanline_len and therefor use
+ scanline_len = 1 which would be very slow */
+ if (fs->predictor == PDF_STM_F_PREDDEC_NO_PREDICTION)
+ {
+ tocpy = PDF_MIN (out->size - out->wp, in->wp - in->rp);
+ memcpy(out->data + out->wp, in->data + in->rp, tocpy);
+ out->wp += tocpy;
+ in->rp += tocpy;
+ }
+
+ /* copy in->data to buffer and filter it */
+ do
+ {
+ in_size = in->wp - in->rp;
+ tocpy = fs->curr_row_buf->size - fs->curr_row_buf->wp;
+ /* PNG predictor needs 1 byte more in a scanline */
+ tocpy -= (is_png_predictor? 0 : 1);
+ tocpy = PDF_MIN (in_size, tocpy);
+
+ memcpy (fs->curr_row_buf->data + fs->curr_row_buf->wp, in->data + in->rp,
+ tocpy);
+
+ fs->curr_row_buf->wp += tocpy;
+ in->rp += tocpy;
+
+ /* curr_row_buf has a scanline (+PNG predictor) and is ready to filter */
+ if (fs->scanline_len == fs->curr_row_buf->wp - fs->curr_row_buf->rp
+ - (is_png_predictor ? 1 : 0))
+ {
+ /* check if out buffer has enough space left */
+ pdf_size_t left;
+ left = fs->out_row_buf->size - fs->out_row_buf->wp;
+ /* PNG predictor needs extra byte per row */
+ if (left >= fs->scanline_len + (is_png_predictor? 1 : 0))
+ {
+ /* write/read PNG predictor at first byte of a row */
+ if (is_png_predictor)
+ fs->predictor = fs->curr_row_buf->data[fs->curr_row_buf->rp++];
+
+ curr_row = (pdf_char_t*) fs->curr_row_buf->data
+ + fs->curr_row_buf->rp;
+ out_buf = (pdf_char_t*) fs->out_row_buf->data
+ + fs->out_row_buf->wp;
+
+ /* at first row decode_row expects prev_row to be NULL */
+ if (fs->prev_row_buf->wp == 0)
+ prev_row = NULL;
+ else
+ prev_row = (pdf_char_t*) fs->prev_row_buf->data;
+
+ if (decode_row (curr_row, out_buf, prev_row, fs, error)
+ == PDF_ERROR)
+ return PDF_STM_FILTER_APPLY_STATUS_ERROR;
+
+ fs->out_row_buf->wp += fs->scanline_len;
+
+ /* copying out_row to prev_row */
+ memcpy (fs->prev_row_buf->data, fs->out_row_buf->data,
+ fs->out_row_buf->size);
+ fs->prev_row_buf->rp = fs->out_row_buf->rp;
+ fs->prev_row_buf->wp = fs->out_row_buf->wp;
+
+ pdf_buffer_rewind (fs->curr_row_buf);
+ }
+ }
+
+ /* out_row_buf has data that can be written to out buffer */
+ if (out->size - out->wp > 0 && !pdf_buffer_eob_p (fs->out_row_buf))
+ {
+ tocpy = PDF_MIN (fs->out_row_buf->wp - fs->out_row_buf->rp,
+ out->size - out->wp);
+
+ memcpy (out->data + out->wp,
+ fs->out_row_buf->data + fs->out_row_buf->rp, tocpy);
+
+ out->wp += tocpy;
+ fs->out_row_buf->rp += tocpy;
+ }
+ if (pdf_buffer_eob_p (fs->out_row_buf))
+ {
+ pdf_buffer_rewind (fs->out_row_buf);
+ }
+ }
+ while (!pdf_buffer_eob_p (in));
+
+ /* final call of this filter; empty out_row_buf */
+ if (finish && in->wp - in->rp < 1)
+ {
+ /* out_row_buf has data because out is full */
+ if (!pdf_buffer_eob_p (fs->out_row_buf))
+ return PDF_STM_FILTER_APPLY_STATUS_NO_OUTPUT;
+ /* input % scanline_len != 0 */
+ if (!pdf_buffer_eob_p (fs->curr_row_buf))
+ {
+ pdf_set_error (error,
+ PDF_EDOMAIN_BASE_STM,
+ PDF_EBADDATA,
+ "filtering with predictor decoder is incomplete: "
+ "out of data in the middle of a scanline "
+ "or wrong columns parameter detected");
+ return PDF_STM_FILTER_APPLY_STATUS_ERROR;
+ }
+
+ return PDF_STM_FILTER_APPLY_STATUS_EOF;
+ }
+
+ return PDF_STM_FILTER_APPLY_STATUS_NO_INPUT;
+}
+
+static void
+stm_f_pred_deinit (void *state)
+{
+ pdf_stm_f_pred_t *filter_state = state;
+
+ pdf_buffer_destroy (filter_state->prev_row_buf);
+ pdf_buffer_destroy (filter_state->curr_row_buf);
+ pdf_buffer_destroy (filter_state->out_row_buf);
+ pdf_dealloc (state);
}
/* End of pdf_stm_f_pred.c */
=== modified file 'src/base/pdf-stm-f-pred.h'
--- src/base/pdf-stm-f-pred.h 2010-02-20 16:02:07 +0000
+++ src/base/pdf-stm-f-pred.h 2011-07-30 21:08:22 +0000
@@ -7,7 +7,7 @@
*
*/
-/* Copyright (C) 2007, 2008 Free Software Foundation, Inc. */
+/* Copyright (C) 2007-2011 Free Software Foundation, Inc. */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,92 +26,14 @@
#ifndef PDF_STM_F_PRED_H
#define PDF_STM_F_PRED_H
-/* BEGIN PUBLIC */
-
-typedef enum
-{
- PDF_STM_F_PREDENC_NO_PREDICTION = 1,
- PDF_STM_F_PREDENC_TIFF_PREDICTOR_2 = 2,
- PDF_STM_F_PREDENC_PNG_NONE_ALL_ROWS = 10,
- PDF_STM_F_PREDENC_PNG_SUB_ALL_ROWS = 11,
- PDF_STM_F_PREDENC_PNG_UP_ALL_ROWS = 12,
- PDF_STM_F_PREDENC_PNG_AVERAGE_ALL_ROWS = 13,
- PDF_STM_F_PREDENC_PNG_PAETH_ALL_ROWS = 14,
- PDF_STM_F_PREDENC_PNG_OPTIMUM = 15
-} pdf_stm_f_predenc_method_t;
-
-typedef enum
-{
- PDF_STM_F_PREDDEC_NO_PREDICTION = 1,
- PDF_STM_F_PREDDEC_TIFF_PREDICTOR_2 = 2,
- PDF_STM_F_PREDDEC_PNG = 3
-} pdf_stm_f_preddec_type_t;
-
-typedef enum
-{
- PDF_STM_F_PREDDEC_PNG_NONE = 10,
- PDF_STM_F_PREDDEC_PNG_SUB = 11,
- PDF_STM_F_PREDDEC_PNG_UP = 12,
- PDF_STM_F_PREDDEC_PNG_AVERAGE = 13,
- PDF_STM_F_PREDDEC_PNG_PAETH = 14
-} pdf_stm_f_predec_png_type_t;
-
-typedef enum {
- PDF_STM_F_PRED_MODE_ENCODE,
- PDF_STM_F_PRED_MODE_DECODE
-} pdf_stm_f_pred_mode_t;
-
-/* END PUBLIC */
-
-/* Configuration structure */
-
-struct pdf_stm_f_pred_conf_s
-{
- int mode; /* It might be encode or decode. */
- int predictor; /* A code that selects the predictor algorithm. If
- the value of this entry is 1, the filter assumes
- that the normal algorithm was used to encode the
- data, without prediction. If the value is greater
- than 1, the filter assumes that the data was
- differenced before being encoded, and `predictor'
- selects the predictor algorithm */
-
-
- /* The following parameters are only useful when `predictor' > 1 */
- int colors; /* Number of interleaved color components
- per sample. Valid values are 1 or
- greater. Default value: 1 */
- int bits_per_component; /* The number of bits used to represent
- each color component in a sample. Valid
- values are 1, 2, 4, 8 and 16. Default
- value: 1 */
- int columns; /* The number of samples in each
- row. Default value: 1 */
-};
-
-typedef struct pdf_stm_f_pred_conf_s *pdf_stm_f_pred_conf_t;
-
-/* Private data */
-
-struct pdf_stm_f_pred_data_s
-{
- int mode;
- int predictor;
- int colors;
- int bits_per_component;
- int columns;
- int scanline_len;
-};
-
-typedef struct pdf_stm_f_pred_data_s *pdf_stm_f_pred_data_t;
-
-/* Filter API implementation */
-
-int pdf_stm_f_pred_init (void **filter_data, void *conf_data);
-int pdf_stm_f_pred_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_pred_dealloc (void **filter_data);
+
+#include
+#include
+
+const pdf_stm_filter_impl_t *pdf_stm_f_preddec_get (void);
+
+const pdf_stm_filter_impl_t *pdf_stm_f_predenc_get (void);
+
#endif /* pdf_stm_f_pred.h */
=== modified file 'src/base/pdf-stm-filter.c'
--- src/base/pdf-stm-filter.c 2011-05-18 18:30:48 +0000
+++ src/base/pdf-stm-filter.c 2011-07-30 21:08:22 +0000
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
/* Build-dependent filters */
@@ -92,8 +93,8 @@
{ "JPX encoder", NULL },
{ "JPX decoder", NULL },
/* Predictors */
- { "Predictor encoder", NULL },
- { "Predictor decoder", NULL },
+ { "Predictor encoder", pdf_stm_f_predenc_get },
+ { "Predictor decoder", pdf_stm_f_preddec_get },
/* Crypt filters */
{ "AESv2 encoder", pdf_stm_f_aesv2enc_get },
{ "AESv2 decoder", pdf_stm_f_aesv2dec_get },
=== modified file 'utils/pdf-filter.c'
--- utils/pdf-filter.c 2011-07-07 15:29:22 +0000
+++ utils/pdf-filter.c 2011-07-30 21:08:22 +0000
@@ -60,6 +60,7 @@
enum
{
+ FILTER_INSTALL_NONE,
HELP_ARG,
VERSION_ARG,
READ_ARG,
@@ -74,9 +75,15 @@
#if 0
CCITTFAXDEC_FILTER_ARG,
JXPDEC_FILTER_ARG,
+#endif /* 0 */
+ PRED_COLORS_ARG,
+ PRED_BITSPERCOMPONENT_ARG,
+ PRED_COLUMNS_ARG,
+ PRED_PREDICTOR_ARG,
PREDENC_FILTER_ARG,
PREDDEC_FILTER_ARG,
-#endif /* 0 */
+ PREDENC_FILTER_INSTALL,
+ PREDDEC_FILTER_INSTALL,
#ifdef HAVE_LIBJPEG
DCTDEC_FILTER_ARG,
#endif /* HAVE_LIBJPEG */
@@ -90,18 +97,37 @@
JBIG2DEC_FILTER_ARG,
JBIG2DEC_GLOBAL_SEGMENTS_ARG,
JBIG2DEC_PAGE_SIZE,
+ JBIG2DEC_FILTER_INSTALL,
#endif /* HAVE_LIBJBIG2DEC */
LZWENC_FILTER_ARG,
LZWDEC_FILTER_ARG,
LZW_EARLYCHANGE_ARG,
+ LZWENC_FILTER_INSTALL,
+ LZWDEC_FILTER_INSTALL,
MD5ENC_FILTER_ARG,
KEY_ARG,
AESENC_FILTER_ARG,
AESDEC_FILTER_ARG,
+ AESENC_FILTER_INSTALL,
+ AESDEC_FILTER_INSTALL,
V2ENC_FILTER_ARG,
- V2DEC_FILTER_ARG
+ V2DEC_FILTER_ARG,
+ V2ENC_FILTER_INSTALL,
+ V2DEC_FILTER_INSTALL
};
+/* name filter args here */
+#define IS_FILTER_ARG(arg) \
+ ((arg) == PRED_COLORS_ARG || \
+ (arg) == PRED_BITSPERCOMPONENT_ARG || \
+ (arg) == PRED_COLUMNS_ARG || \
+ (arg) == PRED_PREDICTOR_ARG || \
+ (arg) == JBIG2DEC_GLOBAL_SEGMENTS_ARG || \
+ (arg) == JBIG2DEC_PAGE_SIZE || \
+ (arg) == LZW_EARLYCHANGE_ARG || \
+ (arg) == KEY_ARG)
+
+
static const struct option GNU_longOptions[] =
{
{"help", no_argument, NULL, HELP_ARG},
@@ -118,11 +144,15 @@
{"lzw-earlychange", no_argument, NULL, LZW_EARLYCHANGE_ARG},
{"a85dec", no_argument, NULL, ASCII85DEC_FILTER_ARG},
{"a85enc", no_argument, NULL, ASCII85ENC_FILTER_ARG},
+ {"predenc", no_argument, NULL, PREDENC_FILTER_ARG},
+ {"preddec", no_argument, NULL, PREDDEC_FILTER_ARG},
+ {"pred-type", required_argument, NULL, PRED_PREDICTOR_ARG},
+ {"pred-colors", required_argument, NULL, PRED_COLORS_ARG},
+ {"pred-bpc", required_argument, NULL, PRED_BITSPERCOMPONENT_ARG},
+ {"pred-columns", required_argument, NULL, PRED_COLUMNS_ARG},
#if 0
{"cfaxdec", no_argument, NULL, CCITTFAXDEC_FILTER_ARG},
{"jxpdec", no_argument, NULL, JXPDEC_FILTER_ARG},
- {"predenc", no_argument, NULL, PREDENC_FILTER_ARG},
- {"preddec", no_argument, NULL, PREDDEC_FILTER_ARG},
#endif /* 0 */
#ifdef PDF_HAVE_LIBJPEG
{"dctdec", no_argument, NULL, DCTDEC_FILTER_ARG},
@@ -168,12 +198,12 @@
--lzwenc use the LZW encoder filter\n\
--lzwdec use the LZW decoder filter\n\
--a85dec use the ASCII 85 decoder filter\n\
- --a85enc use the ASCII 85 encoder filter\n"
-#if 0
-"\
- --jxpdec use the JXP decoder filter\n\
+ --a85enc use the ASCII 85 encoder filter\n\
--predenc use the predictor encoder filter\n\
--preddec use the predictor decoder filter\n"
+#if 0
+ --jxpdec use the JXP decoder filter\n\
+
#endif /* 0 */
#ifdef PDF_HAVE_LIBJPEG
"\
@@ -197,16 +227,11 @@
--help print a help message and exit\n\
--version print a version message and exit\n\
\n\
-Filter properties\n"
-#if 0
-"\
- --preddec-type=NUM code for next preddec filters type\n\
- --predenc-type=NUM code for next predenc filters type\n\
+Filter properties\n\
+ --pred-type=NUM code for next pred 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 */
-"\
+ --pred-columns=NUM next predictors number of samples per row\n\
--lzw-earlychange toggles earlychange for next lzw filters\n\
--jbig2dec-globals=FILE file containing global segments\n\
\n"
@@ -324,7 +349,7 @@
else
{
/* Write stdin into the write stream,
- which will be transparently writting the output to stdout. */
+ which will be transparently writting the output to stdout. */
do
{
if (read_pdf_fsys)
@@ -392,11 +417,11 @@
*read_mode = PDF_FALSE;
while (!finish &&
- (ci = getopt_long (argc,
- argv,
- "i:o:",
- GNU_longOptions,
- NULL)) != -1)
+ (ci = getopt_long (argc,
+ argv,
+ "i:o:",
+ GNU_longOptions,
+ NULL)) != -1)
{
c = ci;
switch (c)
@@ -562,14 +587,25 @@
pdf_stm_t *stm,
int ci)
{
- char c;
- pdf_status_t ret;
pdf_hash_t *filter_params = NULL;
FILE *file;
char *key = NULL;
- pdf_status_t status;
+ pdf_char_t *endptr = NULL; /* Used in strtol */
pdf_bool_t lzw_earlychange = PDF_FALSE;
+ /* parameters for predictior filter */
+ int pred_predictor;
+ int pred_colors;
+ int pred_bpc;
+ int pred_columns;
+ pdf_bool_t pred_predictor_is_set = PDF_FALSE;
+ pdf_bool_t pred_colors_is_set = PDF_FALSE;
+ pdf_bool_t pred_bpc_is_set = PDF_FALSE;
+ pdf_bool_t pred_columns_set = PDF_FALSE;
+
pdf_error_t *error = NULL;
+ char filter_to_install = FILTER_INSTALL_NONE;
+ char *old_optarg = optarg;
+ char next_ci = getopt_long (argc, argv, "", GNU_longOptions, NULL);
/* Initialize the crypt module */
if (pdf_crypt_init () != PDF_OK)
@@ -581,8 +617,7 @@
/* Install filters */
do
{
- c = ci;
- switch (c)
+ switch (ci)
{
/* FILTER INSTALLERS */
case NULL_FILTER_ARG:
@@ -699,37 +734,186 @@
{
break;
}
- case PREDENC_FILTER_ARG:
- {
- /* pdf_stm_install_predenc_filter (input,
- PDF_STM_FILTER_READ,
- args.pred_enc_type,
- args.pred_colors,
- args.pred_bpc,
- args.pred_columns); */
+#endif /* 0 */
+ case PRED_COLORS_ARG:
+ {
+ pred_colors = strtol (old_optarg, (char **) &endptr, 10);
+ if ((*endptr != '\0'))
+ {
+ /* Error parsing the number */
+ fprintf (stdout, "%s\n", pdf_filter_help_msg);
+ exit (EXIT_FAILURE);
+ }
+ pred_colors_is_set = PDF_TRUE;
+ break;
+ }
+ case PRED_BITSPERCOMPONENT_ARG:
+ {
+ pred_bpc = strtol (old_optarg, (char **) &endptr, 10);
+ if ((*endptr != '\0'))
+ {
+ /* Error parsing the number */
+ fprintf (stdout, "%s\n", pdf_filter_help_msg);
+ exit (EXIT_FAILURE);
+ }
+ pred_bpc_is_set = PDF_TRUE;
+ break;
+ }
+ case PRED_COLUMNS_ARG:
+ {
+ pred_columns = strtol (old_optarg, (char **) &endptr, 10);
+ if ((*endptr != '\0'))
+ {
+ /* Error parsing the number */
+ fprintf (stdout, "%s\n", pdf_filter_help_msg);
+ exit (EXIT_FAILURE);
+ }
+ pred_columns_set = PDF_TRUE;
+ break;
+ }
+ case PRED_PREDICTOR_ARG:
+ {
+ pred_predictor = strtol (old_optarg, (char **) &endptr, 10);
+ if ((*endptr != '\0'))
+ {
+ /* Error parsing the number */
+ fprintf (stdout, "%s\n", pdf_filter_help_msg);
+ exit (EXIT_FAILURE);
+ }
+ pred_predictor_is_set = PDF_TRUE;
+ break;
+ }
+ case PREDENC_FILTER_ARG: /* Note that both ENC and DEC go here */
+ {
+ filter_to_install = PREDENC_FILTER_INSTALL;
+
+ /* set parameters as not set */
+ pred_predictor_is_set = PDF_FALSE;
+ pred_colors_is_set = PDF_FALSE;
+ pred_bpc_is_set = PDF_FALSE;
+ pred_columns_set = PDF_FALSE;
break;
}
case PREDDEC_FILTER_ARG:
{
- /* pdf_stm_install_preddec_filter (input,
- PDF_STM_FILTER_READ,
- args.pred_dec_type,
- args.pred_colors,
- args.pred_bpc,
- args.pred_columns); */
- break;
- }
-#endif /* 0 */
-
+ filter_to_install = PREDDEC_FILTER_INSTALL;
+
+ /* set parameters as not set */
+ pred_predictor_is_set = PDF_FALSE;
+ pred_colors_is_set = PDF_FALSE;
+ pred_bpc_is_set = PDF_FALSE;
+ pred_columns_set = PDF_FALSE;
+ break;
+ }
+ case PREDENC_FILTER_INSTALL:
+ case PREDDEC_FILTER_INSTALL:
+ {
+ filter_params = pdf_hash_new (&error);
+ if (!filter_params)
+ {
+ pdf_error (pdf_error_get_status (error),
+ stderr,
+ "couldn't create hash table: '%s'",
+ pdf_error_get_message (error));
+ exit (EXIT_FAILURE);
+ }
+
+ if (pred_colors_is_set)
+ {
+ if (!pdf_hash_add_size (filter_params,
+ "Colors",
+ pred_colors,
+ &error))
+ {
+ pdf_error (pdf_error_get_status (error),
+ stderr,
+ "while creating the predictor filter: '%s'",
+ pdf_error_get_message (error));
+ exit (EXIT_FAILURE);
+ }
+ }
+ if (pred_bpc_is_set)
+ {
+ if (!pdf_hash_add_size (filter_params,
+ "BitsPerComponent",
+ pred_bpc,
+ &error))
+ {
+ pdf_error (pdf_error_get_status (error),
+ stderr,
+ "while creating the predictor filter: '%s'",
+ pdf_error_get_message (error));
+ exit (EXIT_FAILURE);
+ }
+ }
+ if (pred_columns_set)
+ {
+ if (!pdf_hash_add_size (filter_params,
+ "Columns",
+ pred_columns,
+ &error))
+ {
+ pdf_error (pdf_error_get_status (error),
+ stderr,
+ "while creating the predictor filter: '%s'",
+ pdf_error_get_message (error));
+ exit (EXIT_FAILURE);
+ }
+ }
+ if (pred_predictor_is_set)
+ {
+ if (!pdf_hash_add_size (filter_params,
+ "Predictor",
+ pred_predictor,
+ &error))
+ {
+ pdf_error (pdf_error_get_status (error),
+ stderr,
+ "while creating the predictor filter: '%s'",
+ pdf_error_get_message (error));
+ exit (EXIT_FAILURE);
+ }
+ }
+ if (!pdf_stm_install_filter (stm,
+ (ci == PREDENC_FILTER_INSTALL ?
+ PDF_STM_FILTER_PRED_ENC :
+ PDF_STM_FILTER_PRED_DEC),
+ filter_params,
+ &error))
+ {
+ pdf_error (pdf_error_get_status (error),
+ stderr,
+ "while installing the predictor encoder or decoder filter: '%s'",
+ pdf_error_get_message (error));
+ exit (EXIT_FAILURE);
+ }
+ pdf_hash_destroy (filter_params);
+ break;
+ }
case LZW_EARLYCHANGE_ARG:
{
lzw_earlychange = PDF_TRUE;
break;
}
+ case LZWENC_FILTER_ARG:
+ {
+ filter_to_install = LZWENC_FILTER_INSTALL;
- case LZWENC_FILTER_ARG: /* Note that both ENC and DEC go here */
+ /* set default value */
+ lzw_earlychange = PDF_FALSE;
+ break;
+ }
case LZWDEC_FILTER_ARG:
{
+ filter_to_install = LZWDEC_FILTER_INSTALL;
+
+ /* set default value */
+ lzw_earlychange = PDF_FALSE;
+ break;
+ }
+ case LZWENC_FILTER_INSTALL: /* Note that both ENC and DEC go here */
+ case LZWDEC_FILTER_INSTALL:
+ {
filter_params = pdf_hash_new (&error);
if (!filter_params)
{
@@ -753,7 +937,7 @@
}
if (!pdf_stm_install_filter (stm,
- (c == LZWENC_FILTER_ARG ?
+ (ci == LZWENC_FILTER_INSTALL ?
PDF_STM_FILTER_LZW_ENC :
PDF_STM_FILTER_LZW_DEC),
filter_params,
@@ -846,10 +1030,10 @@
{
struct stat fstats;
- stat (optarg, &fstats);
+ stat (old_optarg, &fstats);
/* Load the contents of a jbig2 global segments file */
- file = fopen (optarg, "r");
+ file = fopen (old_optarg, "r");
if (file == NULL)
{
fprintf (stderr, "error: invalid jbig2 global segments file\n");
@@ -873,6 +1057,11 @@
case JBIG2DEC_FILTER_ARG:
{
+ filter_to_install = JBIG2DEC_FILTER_INSTALL;
+ break;
+ }
+ case JBIG2DEC_FILTER_INSTALL:
+ {
if (jbig2dec_global_segments != NULL)
{
filter_params = pdf_hash_new (&error);
@@ -959,13 +1148,23 @@
key = NULL;
}
- key = strdup (optarg);
+ key = strdup (old_optarg);
break;
}
- case AESENC_FILTER_ARG: /* Note that both ENC and DEC go here */
+ case AESENC_FILTER_ARG:
+ {
+ filter_to_install = AESENC_FILTER_INSTALL;
+ break;
+ }
case AESDEC_FILTER_ARG:
{
+ filter_to_install = AESDEC_FILTER_INSTALL;
+ break;
+ }
+ case AESENC_FILTER_INSTALL: /* Note that both ENC and DEC go here */
+ case AESDEC_FILTER_INSTALL:
+ {
if (key == NULL)
{
fprintf (stderr, "You should specify a key for the AESv2 filter.\n");
@@ -1007,7 +1206,7 @@
}
if (!pdf_stm_install_filter (stm,
- (c == AESENC_FILTER_ARG ?
+ (ci == AESENC_FILTER_INSTALL ?
PDF_STM_FILTER_AESV2_ENC :
PDF_STM_FILTER_AESV2_DEC),
filter_params,
@@ -1025,9 +1224,19 @@
break;
}
- case V2ENC_FILTER_ARG: /* Note that both ENC and DEC go here */
+ case V2ENC_FILTER_ARG:
+ {
+ filter_to_install = V2ENC_FILTER_INSTALL;
+ break;
+ }
case V2DEC_FILTER_ARG:
{
+ filter_to_install = V2DEC_FILTER_INSTALL;
+ break;
+ }
+ case V2ENC_FILTER_INSTALL: /* Note that both ENC and DEC go here */
+ case V2DEC_FILTER_INSTALL:
+ {
if (key == NULL)
{
fprintf (stderr, "You should specify a key for the V2 filter.\n");
@@ -1069,7 +1278,7 @@
}
if (!pdf_stm_install_filter (stm,
- (c == V2ENC_FILTER_ARG ?
+ (ci == V2ENC_FILTER_INSTALL ?
PDF_STM_FILTER_V2_ENC :
PDF_STM_FILTER_V2_DEC),
filter_params,
@@ -1097,13 +1306,34 @@
break;
}
}
+
+ /* have we installed a delayed filter in this loop? */
+ if (filter_to_install == ci)
+ {
+ /* no filter delayed anymore */
+ filter_to_install = FILTER_INSTALL_NONE;
+ }
+
+ /* next arg is a new filter and current filter is with args */
+ if (!IS_FILTER_ARG(next_ci) && filter_to_install != FILTER_INSTALL_NONE)
+ {
+ /* do extra loop installing current filter */
+ ci = filter_to_install;
+ }
+ else
+ {
+ ci = next_ci;
+ old_optarg = optarg;
+ next_ci = getopt_long (argc, argv, "", GNU_longOptions, NULL);
+ }
+
+ if (ci == -1 && filter_to_install != FILTER_INSTALL_NONE)
+ {
+ /* end of args and one filter still to install */
+ ci = filter_to_install;
+ }
}
- while ((ci = getopt_long (argc,
- argv,
- "",
- GNU_longOptions,
- NULL)) != -1);
-
+ while (ci != -1);
}
static pdf_fsys_file_t *
# Begin bundle
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