# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: address@hidden # 11j9s27lbhng6ba2 # target_branch: bzr://bzr.savannah.gnu.org/pdf/libgnupdf/trunk/ # testament_sha1: 3daa95922e536e842c729f3acec153b66eba5172 # timestamp: 2011-11-17 19:36:18 +0100 # base_revision_id: address@hidden # # Begin patch === modified file 'ChangeLog' --- ChangeLog 2011-10-11 21:17:52 +0000 +++ ChangeLog 2011-11-17 18:35:09 +0000 @@ -1,3 +1,10 @@ +2011-11-17 Georg Gottleuber + + base,stm: Bugfixes and refactored prediction filter. + * src/base/pdf-stm-f-pred.c: predictor type inside PNG with offset, + PNG predictor functions now process the corresponding bytes; refactored + paeth predictor function + 2011-10-11 Jose E. Marchesi prmgt: converters to html reverted to a previous revision. === modified file 'src/base/pdf-stm-f-pred.c' --- src/base/pdf-stm-f-pred.c 2011-07-30 21:08:22 +0000 +++ src/base/pdf-stm-f-pred.c 2011-11-17 18:35:09 +0000 @@ -107,7 +107,10 @@ pdf_size_t columns; /* The number of samples in each row. Default value: 1 */ - pdf_size_t scanline_len; /* will be calculated from params */ + /* will be calculated from params */ + pdf_size_t scanline_len; /* length of one image row in bytes */ + + pdf_size_t bpp; /* bits per pixel in bytes */ /* previous and current buffers for scanlines (rows) encoder uses prev_row_buf for last input row to the filter @@ -148,7 +151,7 @@ */ typedef struct pred_bit_ptr_s { - pdf_char_t* ptr; + pdf_uchar_t* ptr; int offset; int mask; int block_size; @@ -156,7 +159,7 @@ static void pred_bit_ptr_init (pred_bit_ptr_t* bp, - pdf_char_t* ptr, + pdf_uchar_t* ptr, int block_size) { bp->ptr = ptr; @@ -190,7 +193,7 @@ pdf_error_t **error) { pdf_size_t actual_len; - pdf_stm_f_pred_t* filter_state; + pdf_stm_f_pred_t* fstate; /* Predictor decides if we need more paramters; so check it first */ if (!params || !pdf_hash_key_p (params, PRED_PARAM_PREDICTOR)) @@ -226,9 +229,9 @@ } } - /* Create the private filter_state storage */ - filter_state = pdf_alloc (sizeof (struct pdf_stm_f_pred_s)); - if (!filter_state) + /* Create the private filter state storage */ + fstate = pdf_alloc (sizeof (struct pdf_stm_f_pred_s)); + if (!fstate) { pdf_set_error (error, PDF_EDOMAIN_BASE_STM, @@ -239,25 +242,25 @@ 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); + fstate->predictor = pdf_hash_get_size (params, PRED_PARAM_PREDICTOR); + fstate->colors = pdf_hash_get_size (params, PRED_PARAM_COLORS); + fstate->bits_per_component = pdf_hash_get_size (params, PRED_PARAM_BPC); + fstate->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) + if (fstate->predictor == PDF_STM_F_PREDENC_NO_PREDICTION) { /* set default values */ - filter_state->colors = 1; - filter_state->bits_per_component = 1; - filter_state->columns = 1; + fstate->colors = 1; + fstate->bits_per_component = 1; + fstate->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) + if (fstate->colors < 1 + || fstate->columns < 1 + || fstate->bits_per_component < 1) { pdf_set_error (error, PDF_EDOMAIN_BASE_STM, @@ -265,11 +268,11 @@ "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) ? + ((fstate->colors < 1) ? + "bad" : "ok"), + ((fstate->bits_per_component < 1) ? + "bad" : "ok"), + ((fstate->columns < 1) ? "bad" : "ok")); return PDF_FALSE; } @@ -278,89 +281,96 @@ /* 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 = filter_state->columns * filter_state->colors * - filter_state->bits_per_component; - filter_state->scanline_len = (actual_len >> 3) + (actual_len & 7); + actual_len = fstate->columns * fstate->colors * + fstate->bits_per_component; + fstate->scanline_len = (actual_len >> 3) + (actual_len & 7); + + fstate->bpp = (fstate->colors * fstate->bits_per_component + 7) / 8; /* one extra byte for PNG predictor */ - filter_state->prev_row_buf = pdf_buffer_new (filter_state->scanline_len + 1, + fstate->prev_row_buf = pdf_buffer_new (fstate->scanline_len + 1, error); - if (!(filter_state->prev_row_buf)) + if (!(fstate->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); + (unsigned long) fstate->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, + fstate->curr_row_buf = pdf_buffer_new (fstate->scanline_len + 1, error); - if (!(filter_state->curr_row_buf)) + if (!(fstate->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); + (unsigned long) fstate->scanline_len); return PDF_FALSE; } - filter_state->out_row_buf = pdf_buffer_new (filter_state->scanline_len + 1, + fstate->out_row_buf = pdf_buffer_new (fstate->scanline_len + 1, error); - if (!(filter_state->out_row_buf)) + if (!(fstate->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); + (unsigned long) fstate->scanline_len + 1); return PDF_FALSE; } - *state = filter_state; + *state = fstate; return PDF_TRUE; } - static void -encode_row_none(pdf_char_t* cur, - pdf_char_t* prev, - pdf_char_t* out, +encode_row_none(pdf_uchar_t* cur, + pdf_uchar_t* prev, + pdf_uchar_t* out, pdf_stm_f_pred_t* state) { memcpy(out, cur, state->scanline_len); } static void -encode_row_sub(pdf_char_t* cur, - pdf_char_t* prev, - pdf_char_t* out, +encode_row_sub(pdf_uchar_t* cur, + pdf_uchar_t* prev, + pdf_uchar_t* out, pdf_stm_f_pred_t* state) { pdf_size_t i; - *out++ = *cur++; - for (i = 1; i < state->scanline_len; i++) - { - *out++ = *cur - *(cur-1); + + for( i = 0 ; i < state->bpp ; i++ ) + { + *out++ = *cur++; + } + + for (i = 0; i < state->scanline_len - state->bpp; i++) + { + *out++ = *cur - *(cur - state->bpp); cur++; } } static void -encode_row_up(pdf_char_t* cur, - pdf_char_t* prev, - pdf_char_t* out, +encode_row_up(pdf_uchar_t* cur, + pdf_uchar_t* prev, + pdf_uchar_t* out, pdf_stm_f_pred_t* state) { pdf_size_t i; - if (prev != NULL) + + if (prev != NULL) { for (i = 0; i < state->scanline_len; i++) { @@ -374,96 +384,104 @@ } static void -encode_row_average(pdf_char_t* cur, - pdf_char_t* prev, - pdf_char_t* out, +encode_row_average(pdf_uchar_t* cur, + pdf_uchar_t* prev, + pdf_uchar_t* out, pdf_stm_f_pred_t* state) { pdf_size_t i; + pdf_size_t bpp = state->bpp; + if (prev != NULL) { - *out++ = *cur++ - (*prev++ >> 1); + for( i = 0 ; i < bpp ; i++ ) + { + *out++ = *cur++ - (*prev++ >> 1); + } - for (i = 1; i < state->scanline_len; i++) + for (i = 0; i < state->scanline_len - bpp; i++) { - *out++ = *cur - (pdf_char_t)(((int)*(cur-1) + (int)*prev) >> 1); + *out++ = *cur - (pdf_uchar_t) (((int) cur[-bpp] + (int) *prev) >> 1); cur++; prev++; } - } - else + } + else { - *out++ = *cur++; + for( i = 0 ; i < bpp ; i++ ) + { + *out++ = *cur++; + } - for (i = 1; i < state->scanline_len; i++) + for (i = 0; i < state->scanline_len - bpp; i++) { - *out++ = *cur - (*(cur-1) >> 1); + *out++ = *cur - (cur[-bpp] >> 1); cur++; } } } +static int +paeth_predictor(int a, int b, int c) +{ + int p = a + b - c; + int pa = abs(p - a); + int pb = abs(p - b); + int pc = abs(p - c); + + if (pa <= pb && pa <= pc) + return a; + if (pb <= pc) + return b; + + return c; +} + + static void -encode_row_paeth (pdf_char_t* cur, - pdf_char_t* prev, - pdf_char_t* out, +encode_row_paeth (pdf_uchar_t* cur, + pdf_uchar_t* prev, + pdf_uchar_t* out, pdf_stm_f_pred_t* state) { pdf_size_t i; - int p; - int pa; - int pb; - int pc; + pdf_size_t bpp = state->bpp; - if (prev != NULL) + if (prev != NULL) { - *out++ = *cur++ - *prev++; - - for (i = 0; i < state->scanline_len; i++) - { - p = *(cur-1) + *(prev) - *(prev-1); - pa = abs(p - *(cur-1)); - pb = abs(p - *(prev)); - pc = abs(p - *(prev-1)); - - if (pa <= pb && pa <= pc) - { - *out++ = *cur - *(cur-1); - } - else - { - if (pb <= pc) - { - *out++ = *cur - *(prev); - } - else - { - *out++ = *cur - *(prev-1); - } - } - - cur++; + for (i = 0; i < bpp; i++) + { + *out++ = *cur++ - *prev++; + } + + for (i = 0; i < state->scanline_len - bpp; i++) + { + *out++ = *cur - paeth_predictor (cur[-bpp], prev[0], prev[-bpp]); prev++; + cur++; } - } - else + } + else { - *out++ = *cur++; + for (i = 0; i < bpp; i++) + { + *out++ = *cur++; + } - for (i = 1; i < state->scanline_len; i++) + for (i = 0; i < state->scanline_len - bpp; i++) { - *out++ = *cur - *(cur-1); + *out++ = *cur - cur[-bpp]; cur++; } } } static void -encode_row_sub_color16 (pdf_char_t* cur, - pdf_char_t* prev, - pdf_char_t* out, +encode_row_sub_color16 (pdf_uchar_t* cur, + pdf_uchar_t* prev, + pdf_uchar_t* out, pdf_stm_f_pred_t* state) -{ +{ pdf_size_t i; pdf_size_t j; @@ -490,16 +508,16 @@ } static void -encode_row_sub_color8 (pdf_char_t* cur, - pdf_char_t* prev, - pdf_char_t* out, +encode_row_sub_color8 (pdf_uchar_t* cur, + pdf_uchar_t* prev, + pdf_uchar_t* out, pdf_stm_f_pred_t* state) { pdf_size_t i; pdf_size_t j; - pdf_char_t *this; - pdf_char_t *next; - pdf_char_t *sout; + pdf_uchar_t *this; + pdf_uchar_t *next; + pdf_uchar_t *sout; this = cur; next = cur; @@ -519,9 +537,9 @@ } static void -encode_row_sub_colorl8 (pdf_char_t *cur, - pdf_char_t *prev, - pdf_char_t *out, +encode_row_sub_colorl8 (pdf_uchar_t *cur, + pdf_uchar_t *prev, + pdf_uchar_t *out, pdf_stm_f_pred_t* state) { pdf_size_t i; @@ -529,11 +547,11 @@ pred_bit_ptr_t this; pred_bit_ptr_t next; pred_bit_ptr_t sout; - + 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 < state->colors; j++) { PRED_BIT_PTR_SET(sout, PRED_BIT_PTR_GET(next)); @@ -554,9 +572,9 @@ } static int -encode_row (pdf_char_t *cur, - pdf_char_t *prev, - pdf_char_t *out, +encode_row (pdf_uchar_t *cur, + pdf_uchar_t *prev, + pdf_uchar_t *out, pdf_stm_f_pred_t* state, pdf_error_t **error) { @@ -639,35 +657,38 @@ } static void -decode_row_none (pdf_char_t* in, - pdf_char_t* cur, - pdf_char_t* prev, +decode_row_none (pdf_uchar_t* in, + pdf_uchar_t* cur, + pdf_uchar_t* prev, pdf_stm_f_pred_t* state) { memcpy (cur, in, state->scanline_len); } static void -decode_row_sub (pdf_char_t* in, - pdf_char_t* cur, - pdf_char_t* prev, +decode_row_sub (pdf_uchar_t* in, + pdf_uchar_t* cur, + pdf_uchar_t* prev, pdf_stm_f_pred_t* state) { pdf_size_t i; - *cur++ = *in++; + for( i = 0 ; i < state->bpp ; i++) + { + *cur++ = *in++; + } - for (i = 1; i < state->scanline_len; i++) + for (i = 0; i < state->scanline_len - state->bpp; i++) { - *cur = *in++ + *(cur-1); - cur++; + *cur = *in++ + cur[-state->bpp]; + cur++; } } static void -decode_row_up (pdf_char_t* in, - pdf_char_t* cur, - pdf_char_t* prev, +decode_row_up (pdf_uchar_t* in, + pdf_uchar_t* cur, + pdf_uchar_t* prev, pdf_stm_f_pred_t* state) { pdf_size_t i; @@ -687,94 +708,84 @@ } static void -decode_row_average (pdf_char_t* in, - pdf_char_t* cur, - pdf_char_t* prev, +decode_row_average (pdf_uchar_t* in, + pdf_uchar_t* cur, + pdf_uchar_t* prev, pdf_stm_f_pred_t* state) { pdf_size_t i; + pdf_size_t bpp = state->bpp; if (prev != NULL) { - *cur++ = *in++ + (*prev++ >> 1); + for (i = 0; i < bpp; i++) + { + *cur++ = *in++ + (*prev++ >> 1); + } - for (i = 1; i < state->scanline_len; i++) + for (i = 0; i < state->scanline_len - bpp; i++) { - *cur = *in++ + (pdf_char_t)(((int)*(cur-1) + (int)*prev) >> 1); + *cur = *in++ + (pdf_uchar_t) (((int) cur[-bpp] + (int) *prev) >> 1); cur++; prev++; } - } - else + } + else { - *cur++ = *in++; + for (i = 0; i < bpp; i++) + { + *cur++ = *in++; + } - for (i = 1; i < state->scanline_len; i++) + for (i = 0; i < state->scanline_len - bpp; i++) { - *cur = *in++ + (*(cur-1) >> 1); + *cur = *in++ + (cur[-bpp] >> 1); cur++; } } } static void -decode_row_paeth (pdf_char_t* in, - pdf_char_t* cur, - pdf_char_t* prev, +decode_row_paeth (pdf_uchar_t* in, + pdf_uchar_t* cur, + pdf_uchar_t* prev, pdf_stm_f_pred_t* state) { - int p; - int pa; - int pb; - int pc; pdf_size_t i; + pdf_size_t bpp = state->bpp; - if (prev != NULL) + if (prev != NULL) { - *cur++ = *in++ + *prev++; - - for (i = 0; i < state->scanline_len; i++) - { - p = *(cur-1) + *(prev) - *(prev-1); - pa = abs(p - *(cur-1)); - pb = abs(p - *(prev)); - pc = abs(p - *(prev-1)); - - if (pa <= pb && pa <= pc) - { - *cur = *in + *(cur-1); - } - else - { - if (pb <= pc) - { - *cur = *in + *(prev); - } - else - { - *cur = *in + *(prev-1); - } - } - - in++; + for (i = 0; i < bpp; i++) + { + *cur = *in++ + paeth_predictor (0, *prev++, 0); + cur++; + } + + for (i = 0; i < state->scanline_len - bpp; i++) + { + *cur = *in++ + paeth_predictor (cur[-bpp], prev[0], prev[-bpp]); prev++; cur++; } - } - else + } + else { - *cur++ = *in++; + for (i = 0; i < bpp; i++) + { + *cur++ = *in++; + } - for (i = 1; i < state->scanline_len; i++) + for (i = 0; i < state->scanline_len - bpp; i++) { - *cur = *in++ + *(cur-1); - cur++; + *cur = *in++ + cur[-bpp]; + cur++; } } } static void -decode_row_sub_color16 (pdf_char_t* in, pdf_char_t* cur, pdf_char_t* prev, +decode_row_sub_color16 (pdf_uchar_t* in, pdf_uchar_t* cur, pdf_uchar_t* prev, pdf_stm_f_pred_t* state) { pdf_size_t i; @@ -801,16 +812,16 @@ } static void -decode_row_sub_color8 (pdf_char_t* in, - pdf_char_t* cur, - pdf_char_t* prev, +decode_row_sub_color8 (pdf_uchar_t* in, + pdf_uchar_t* cur, + pdf_uchar_t* prev, pdf_stm_f_pred_t* state) { pdf_size_t i; pdf_size_t j; - pdf_char_t *this; - pdf_char_t *next; - pdf_char_t *sin; + pdf_uchar_t *this; + pdf_uchar_t *next; + pdf_uchar_t *sin; this = cur; next = cur; @@ -832,9 +843,9 @@ static void -decode_row_sub_colorl8 (pdf_char_t* in, - pdf_char_t* cur, - pdf_char_t* prev, +decode_row_sub_colorl8 (pdf_uchar_t* in, + pdf_uchar_t* cur, + pdf_uchar_t* prev, pdf_stm_f_pred_t* state) { pdf_size_t i; @@ -867,9 +878,9 @@ } static int -decode_row (pdf_char_t* in, - pdf_char_t* cur, - pdf_char_t* prev, +decode_row (pdf_uchar_t* in, + pdf_uchar_t* cur, + pdf_uchar_t* prev, pdf_stm_f_pred_t* state, pdf_error_t **error) { @@ -964,11 +975,12 @@ 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_uchar_t *curr_row; + pdf_uchar_t *prev_row = NULL; + pdf_uchar_t *out_buf; pdf_size_t in_size; + pdf_uchar_t png_pred_type; PDF_ASSERT (in->wp >= in->rp); size_t tocpy; @@ -1008,17 +1020,20 @@ { /* 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; + { + /* predictor numbers inside PNG start with 0 (see RFC-2083) */ + png_pred_type = fs->predictor - PDF_STM_F_PREDDEC_PNG_NONE; + fs->out_row_buf->data[fs->out_row_buf->wp++] = png_pred_type; + } - 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; + curr_row = fs->curr_row_buf->data; + out_buf = 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; + prev_row = fs->prev_row_buf->data; if (encode_row (curr_row, prev_row, out_buf, fs, error) == PDF_ERROR) @@ -1096,9 +1111,9 @@ 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_uchar_t *curr_row; + pdf_uchar_t *prev_row = NULL; + pdf_uchar_t *out_buf; pdf_size_t in_size; PDF_ASSERT (in->wp >= in->rp); @@ -1143,18 +1158,34 @@ { /* 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; + { + fs->predictor = fs->curr_row_buf->data[fs->curr_row_buf->rp]; + fs->curr_row_buf->rp++; + /* predictor numbers inside PNG start with 0 (see RFC-2083) */ + fs->predictor += PDF_STM_F_PREDDEC_PNG_NONE; + + /* this prevents jumping from PNG prediction to TIFF + * in the same image */ + if (fs->predictor < PDF_STM_F_PREDDEC_PNG_NONE) + { + pdf_set_error (error, + PDF_EDOMAIN_BASE_STM, + PDF_EBADDATA, + "bad predictor value for decoding a PNG image: " + "expected 10, 11, 12, 13, 14 got %d", + (fs->predictor)); + return PDF_STM_FILTER_APPLY_STATUS_ERROR; + } + } + + curr_row = fs->curr_row_buf->data + fs->curr_row_buf->rp; + out_buf = 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; + prev_row = fs->prev_row_buf->data; if (decode_row (curr_row, out_buf, prev_row, fs, error) == PDF_ERROR) @@ -1189,7 +1220,10 @@ pdf_buffer_rewind (fs->out_row_buf); } } - while (!pdf_buffer_eob_p (in)); + while (!pdf_buffer_eob_p (in) && !pdf_buffer_full_p (out)); + + 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) # Begin bundle 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 P/0+YrYWUcKrVZh/8XckU4UJD7dPB/A=