LTP GCOV extension - code coverage report
Current view: directory - src/base - pdf-stm-filter.c
Test: libgnupdf.info
Date: 2010-07-31 Instrumented lines: 157
Code covered: 92.4 % Executed lines: 145

       1                 : /* -*- mode: C -*-
       2                 :  *
       3                 :  *       File:         pdf-stm-filter.c
       4                 :  *       Date:         Thu Jun 12 22:13:31 2008
       5                 :  *
       6                 :  *       GNU PDF Library - Stream Filter
       7                 :  *
       8                 :  */
       9                 : 
      10                 : /* Copyright (C) 2008, 2009 Free Software Foundation, Inc. */
      11                 : 
      12                 : /* This program is free software: you can redistribute it and/or modify
      13                 :  * it under the terms of the GNU General Public License as published by
      14                 :  * the Free Software Foundation, either version 3 of the License, or
      15                 :  * (at your option) any later version.
      16                 :  *
      17                 :  * This program is distributed in the hope that it will be useful,
      18                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      19                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20                 :  * GNU General Public License for more details.
      21                 :  *
      22                 :  * You should have received a copy of the GNU General Public License
      23                 :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24                 :  */
      25                 : 
      26                 : #include <config.h>
      27                 : 
      28                 : #include <pdf-stm-filter.h>
      29                 : 
      30                 : /* Forward references */
      31                 : static pdf_size_t pdf_stm_filter_get_input (pdf_stm_filter_t filter,
      32                 :                                             pdf_bool_t finish_p);
      33                 : 
      34                 : 
      35                 : /*
      36                 :  * Public functions
      37                 :  */
      38                 : 
      39                 : pdf_status_t
      40                 : pdf_stm_filter_new (enum pdf_stm_filter_type_e type,
      41                 :                     pdf_hash_t params,
      42                 :                     pdf_size_t buffer_size,
      43                 :                     enum pdf_stm_filter_mode_e mode,
      44                 :                     pdf_stm_filter_t *filter)
      45             859 : {
      46             859 :   pdf_status_t init_ret = PDF_ERROR;
      47                 :   pdf_stm_filter_t new;
      48                 : 
      49                 :   /* Allocate the filter structure */
      50             859 :   new = (pdf_stm_filter_t) 
      51                 :     pdf_alloc (sizeof(struct pdf_stm_filter_s));
      52                 : 
      53             859 :   if (new)
      54                 :     {
      55                 :       /* Initialisation */
      56             859 :       new->type = type;
      57                 :       
      58                 :       /* Data sources */
      59             859 :       new->next = NULL;
      60             859 :       new->backend = NULL;
      61                 :       
      62                 :       /* Operation mode */
      63             859 :       new->mode = mode;
      64                 :       
      65                 :       /* Input buffer */
      66             859 :       new->in = pdf_buffer_new (buffer_size);
      67             859 :       if (!new->in)
      68                 :         {
      69                 :           /* Not enough memory. Retreat. */
      70               0 :           pdf_dealloc (new);
      71               0 :           goto exit;
      72                 :         }
      73                 :       
      74                 :       /* Output buffer */
      75             859 :       new->out = NULL;
      76                 :       
      77                 :       /* Install the appropriate implementation */
      78             859 :       switch (new->type)
      79                 :         {
      80                 :         case PDF_STM_FILTER_NULL:
      81                 :           {
      82             806 :             new->impl.init_fn = pdf_stm_f_null_init;
      83             806 :             new->impl.apply_fn = pdf_stm_f_null_apply;
      84             806 :             new->impl.dealloc_state_fn = pdf_stm_f_null_dealloc_state;
      85             806 :             break;
      86                 :           }
      87                 :         case PDF_STM_FILTER_AHEX_ENC:
      88                 :           {
      89               2 :             new->impl.init_fn = pdf_stm_f_ahexenc_init;
      90               2 :             new->impl.apply_fn = pdf_stm_f_ahexenc_apply;
      91               2 :             new->impl.dealloc_state_fn = pdf_stm_f_ahexenc_dealloc_state;
      92               2 :             break;
      93                 :           }
      94                 :         case PDF_STM_FILTER_AHEX_DEC:
      95                 :           {
      96               3 :             new->impl.init_fn = pdf_stm_f_ahexdec_init;
      97               3 :             new->impl.apply_fn = pdf_stm_f_ahexdec_apply;
      98               3 :             new->impl.dealloc_state_fn = pdf_stm_f_ahexdec_dealloc_state;
      99               3 :             break;
     100                 :           }
     101                 :         case PDF_STM_FILTER_RL_ENC:
     102                 :           {
     103               1 :             new->impl.init_fn = pdf_stm_f_rlenc_init;
     104               1 :             new->impl.apply_fn = pdf_stm_f_rlenc_apply;
     105               1 :             new->impl.dealloc_state_fn = pdf_stm_f_rlenc_dealloc_state;
     106               1 :             break;
     107                 :           }
     108                 :         case PDF_STM_FILTER_RL_DEC:
     109                 :           {
     110               1 :             new->impl.init_fn = pdf_stm_f_rldec_init;
     111               1 :             new->impl.apply_fn = pdf_stm_f_rldec_apply;
     112               1 :             new->impl.dealloc_state_fn = pdf_stm_f_rldec_dealloc_state;
     113               1 :             break;
     114                 :           }
     115                 : #if defined PDF_HAVE_LIBZ
     116                 :         case PDF_STM_FILTER_FLATE_ENC:
     117                 :           {
     118               1 :             new->impl.init_fn = pdf_stm_f_flateenc_init;
     119               1 :             new->impl.apply_fn = pdf_stm_f_flateenc_apply;
     120               1 :             new->impl.dealloc_state_fn = pdf_stm_f_flateenc_dealloc_state;
     121               1 :             break;
     122                 :           }
     123                 :         case PDF_STM_FILTER_FLATE_DEC:
     124                 :           {
     125               1 :             new->impl.init_fn = pdf_stm_f_flatedec_init;
     126               1 :             new->impl.apply_fn = pdf_stm_f_flatedec_apply;
     127               1 :             new->impl.dealloc_state_fn = pdf_stm_f_flatedec_dealloc_state;
     128               1 :             break;
     129                 :           }
     130                 : #endif /* PDF_HAVE_LIBZ */
     131                 :         case PDF_STM_FILTER_V2_ENC:
     132                 :           {
     133               2 :             new->impl.init_fn = pdf_stm_f_v2enc_init;
     134               2 :             new->impl.apply_fn = pdf_stm_f_v2enc_apply;
     135               2 :             new->impl.dealloc_state_fn = pdf_stm_f_v2enc_dealloc_state;
     136               2 :             break;
     137                 :           }
     138                 :         case PDF_STM_FILTER_V2_DEC:
     139                 :           {
     140               1 :             new->impl.init_fn = pdf_stm_f_v2dec_init;
     141               1 :             new->impl.apply_fn = pdf_stm_f_v2dec_apply;
     142               1 :             new->impl.dealloc_state_fn = pdf_stm_f_v2dec_dealloc_state;
     143               1 :             break;
     144                 :           }
     145                 :         case PDF_STM_FILTER_AESV2_ENC:
     146                 :           {
     147               2 :             new->impl.init_fn = pdf_stm_f_aesv2enc_init;
     148               2 :             new->impl.apply_fn = pdf_stm_f_aesv2enc_apply;
     149               2 :             new->impl.dealloc_state_fn = pdf_stm_f_aesv2enc_dealloc_state;
     150               2 :             break;
     151                 :           }
     152                 :         case PDF_STM_FILTER_AESV2_DEC:
     153                 :           {
     154               1 :             new->impl.init_fn = pdf_stm_f_aesv2dec_init;
     155               1 :             new->impl.apply_fn = pdf_stm_f_aesv2dec_apply;
     156               1 :             new->impl.dealloc_state_fn = pdf_stm_f_aesv2dec_dealloc_state;
     157               1 :             break;
     158                 :           }
     159                 :         case PDF_STM_FILTER_MD5_ENC:
     160                 :           {
     161               1 :             new->impl.init_fn = pdf_stm_f_md5enc_init;
     162               1 :             new->impl.apply_fn = pdf_stm_f_md5enc_apply;
     163               1 :             new->impl.dealloc_state_fn = pdf_stm_f_md5enc_dealloc_state;
     164               1 :             break;
     165                 :           }
     166                 :         case PDF_STM_FILTER_LZW_ENC:
     167                 :           {
     168               1 :             new->impl.init_fn = pdf_stm_f_lzwenc_init;
     169               1 :             new->impl.apply_fn = pdf_stm_f_lzwenc_apply;
     170               1 :             new->impl.dealloc_state_fn = pdf_stm_f_lzwenc_dealloc_state;
     171               1 :             break;
     172                 :           }
     173                 :         case PDF_STM_FILTER_LZW_DEC:
     174                 :           {
     175               1 :             new->impl.init_fn = pdf_stm_f_lzwdec_init;
     176               1 :             new->impl.apply_fn = pdf_stm_f_lzwdec_apply;
     177               1 :             new->impl.dealloc_state_fn = pdf_stm_f_lzwdec_dealloc_state;
     178               1 :             break;
     179                 :           }
     180                 :         case PDF_STM_FILTER_A85_ENC:
     181                 :           {
     182               5 :             new->impl.init_fn = pdf_stm_f_a85enc_init;
     183               5 :             new->impl.apply_fn = pdf_stm_f_a85enc_apply;
     184               5 :             new->impl.dealloc_state_fn = pdf_stm_f_a85enc_dealloc_state;
     185               5 :             break;
     186                 :           }
     187                 :         case PDF_STM_FILTER_A85_DEC:
     188                 :           {
     189              30 :             new->impl.init_fn = pdf_stm_f_a85dec_init;
     190              30 :             new->impl.apply_fn = pdf_stm_f_a85dec_apply;
     191              30 :             new->impl.dealloc_state_fn = pdf_stm_f_a85dec_dealloc_state;
     192              30 :             break;
     193                 :           }
     194                 : #if defined PDF_HAVE_LIBJBIG2DEC
     195                 :         case PDF_STM_FILTER_JBIG2_DEC:
     196                 :           {
     197               0 :             new->impl.init_fn = pdf_stm_f_jbig2dec_init;
     198               0 :             new->impl.apply_fn = pdf_stm_f_jbig2dec_apply;
     199               0 :             new->impl.dealloc_state_fn = pdf_stm_f_jbig2dec_dealloc_state;
     200                 :             break;
     201                 :           }
     202                 : #endif /* PDF_HAVE_LIBJBIG2DEC */
     203                 : #if defined PDF_HAVE_LIBJPEG
     204                 :         case PDF_STM_FILTER_DCT_DEC:
     205                 :           {
     206                 :             new->impl.init_fn = pdf_stm_f_dctdec_init;
     207                 :             new->impl.apply_fn = pdf_stm_f_dctdec_apply;
     208                 :             new->impl.dealloc_state_fn = pdf_stm_f_dctdec_dealloc_state;
     209                 :             break;
     210                 :           }
     211                 : #endif /* PDF_HAVE_LIBJPEG */
     212                 :         default:
     213                 :           {
     214                 :             /* Shall not be reached, but makes the compiler happy */
     215                 :             break;
     216                 :           }
     217                 :         }
     218                 : 
     219                 :       /* Initialization of the implementation */
     220             859 :       new->params = params;
     221             859 :       new->state = NULL;
     222             859 :       new->status = PDF_OK;
     223             859 :       new->really_finish_p = PDF_FALSE;
     224                 : 
     225             859 :       init_ret = new->impl.init_fn (new->params,
     226                 :                                     &(new->state));
     227             859 :       if (init_ret != PDF_OK)
     228                 :         {
     229                 :           /* Error initializing the filter implementation */
     230               1 :           pdf_buffer_destroy (new->in);
     231               1 :           pdf_dealloc (new);
     232               1 :           new = NULL;
     233                 :         }
     234                 : 
     235             859 :       *filter = new;
     236                 :     }
     237                 : 
     238             859 :  exit:
     239                 : 
     240             859 :   return init_ret;
     241                 : }
     242                 : 
     243                 : pdf_status_t
     244                 : pdf_stm_filter_destroy (pdf_stm_filter_t filter)
     245             673 : {
     246             673 :   pdf_buffer_destroy (filter->in);
     247             673 :   filter->impl.dealloc_state_fn (filter->state);
     248             673 :   pdf_dealloc (filter);
     249                 : 
     250                 :   /* Note that the memory used by the output buffer and by the params
     251                 :      hash is NOT managed by the filter */
     252                 : 
     253             673 :   return PDF_OK;
     254                 : }
     255                 : 
     256                 : inline pdf_status_t
     257                 : pdf_stm_filter_set_next (pdf_stm_filter_t filter,
     258                 :                          pdf_stm_filter_t next_filter)
     259              56 : {
     260              56 :   filter->next = next_filter;
     261              56 :   return PDF_OK;
     262                 : }
     263                 : 
     264                 : inline pdf_status_t
     265                 : pdf_stm_filter_set_be (pdf_stm_filter_t filter,
     266                 :                        pdf_stm_be_t be)
     267             762 : {
     268             762 :   filter->backend = be;
     269             762 :   return PDF_OK;
     270                 : }
     271                 : 
     272                 : inline pdf_status_t
     273                 : pdf_stm_filter_set_out (pdf_stm_filter_t filter,
     274                 :                         pdf_buffer_t buffer)
     275             914 : {
     276             914 :   filter->out = buffer;
     277             914 :   return PDF_OK;
     278                 : }
     279                 : 
     280                 : inline pdf_buffer_t
     281                 : pdf_stm_filter_get_in (pdf_stm_filter_t filter)
     282            1289 : {
     283            1289 :   return filter->in;
     284                 : }
     285                 : 
     286                 : pdf_status_t
     287                 : pdf_stm_filter_apply (pdf_stm_filter_t filter,
     288                 :                       pdf_bool_t finish_p)
     289            6062 : {
     290                 :   pdf_status_t ret;
     291                 :   pdf_status_t apply_ret;
     292                 :   pdf_status_t ret_in;
     293                 : 
     294                 :   /* If the filter is in an error state or it is in an eof state, just
     295                 :      communicate it to the caller */
     296            6062 :   if (filter->status != PDF_OK)
     297                 :     {
     298              14 :       return filter->status;
     299                 :     }
     300                 : 
     301            6048 :   ret = PDF_OK;
     302           14928 :   while (!pdf_buffer_full_p (filter->out))
     303                 :     {
     304                 :       /* Generate output */
     305            8659 :       apply_ret = filter->impl.apply_fn (filter->params,
     306                 :                                          filter->state,
     307                 :                                          filter->in,
     308                 :                                          filter->out,
     309                 :                                          filter->really_finish_p);
     310                 : 
     311            8659 :       if (apply_ret == PDF_ERROR)
     312                 :         {
     313                 :           /* The filter is now in an error condition. We should not
     314                 :              call this filter anymore without a previous reset */
     315              14 :           filter->status = PDF_ERROR;
     316              14 :           ret = filter->status;
     317              14 :           break;
     318                 :         }
     319            8645 :       if (apply_ret == PDF_EEOF)
     320                 :         {
     321                 :           /* The filter is now in an EOF condition. We should not call
     322                 :              this filter anymore without a previous reset */
     323              20 :           filter->status = PDF_EEOF;
     324              20 :           ret = filter->status;
     325              20 :           break;
     326                 :         }
     327            8625 :       if (apply_ret == PDF_ENINPUT)
     328                 :         {
     329                 :           /* The filter needs more input, try to get the input buffer
     330                 :              filled with some data */
     331           14876 :           ret_in = pdf_stm_filter_get_input (filter, finish_p);
     332            7438 :           if (ret_in == PDF_ERROR)
     333                 :             {
     334               0 :               filter->status = PDF_ERROR;
     335               0 :               ret = filter->status;
     336               0 :               break;
     337                 :             }
     338            7438 :           else if ((ret_in == PDF_EEOF) 
     339                 :                    && (pdf_buffer_eob_p (filter->in)))
     340                 :             {
     341            6100 :               if (((filter->mode == PDF_STM_FILTER_MODE_WRITE) 
     342                 :                    && ((finish_p) && (!filter->really_finish_p))) ||
     343                 :                   ((filter->mode == PDF_STM_FILTER_MODE_READ)
     344                 :                    && (!filter->really_finish_p)))
     345                 :                 {
     346             747 :                   filter->really_finish_p = PDF_TRUE;
     347                 :                 }
     348                 :               else
     349                 :                 {
     350            4606 :                   ret = PDF_EEOF;
     351            4606 :                   break;
     352                 :                 }
     353                 :             }
     354                 :         }
     355            4019 :       if (apply_ret == PDF_ENOUTPUT)
     356                 :         {
     357                 :           /* The filter needs to generate output and the output buffer
     358                 :              is full */
     359            1187 :           filter->status = PDF_OK;
     360            1187 :           break;
     361                 :         }
     362                 :     }
     363                 : 
     364            6048 :   return ret;
     365                 : }
     366                 : 
     367                 : pdf_status_t
     368                 : pdf_stm_filter_reset (pdf_stm_filter_t filter)
     369               0 : {
     370               0 :   filter->status = PDF_OK;
     371               0 :   filter->really_finish_p = PDF_FALSE;
     372               0 :   return filter->impl.init_fn (filter->params,
     373                 :                                &(filter->state));
     374                 : }
     375                 : 
     376                 : pdf_stm_filter_t
     377                 : pdf_stm_filter_get_tail (pdf_stm_filter_t filter)
     378            2425 : {
     379            2425 :   if (filter->next == NULL)
     380                 :     {
     381            1233 :       return filter;
     382                 :     }
     383                 :   else
     384                 :     {
     385            1192 :       return pdf_stm_filter_get_tail (filter->next);
     386                 :     }
     387                 : }
     388                 : 
     389                 : /*
     390                 :  * Private functions
     391                 :  */
     392                 : 
     393                 : static pdf_size_t
     394                 : pdf_stm_filter_get_input (pdf_stm_filter_t filter,
     395                 :                           pdf_bool_t finish_p)
     396                 : {
     397                 :   pdf_status_t ret;
     398                 :   pdf_size_t read_bytes;
     399                 : 
     400                 :   /* The input buffer should be empty at this point */
     401            7438 :   pdf_buffer_rewind (filter->in);
     402                 : 
     403            7438 :   ret = PDF_OK;
     404            7438 :   if (filter->next != NULL)
     405                 :     {
     406            2479 :       ret = pdf_stm_filter_apply (filter->next, finish_p);
     407                 :     }
     408            4959 :   else if (filter->backend != NULL)
     409                 :     {
     410            2536 :       read_bytes = pdf_stm_be_read (filter->backend,
     411                 :                                     filter->in->data,
     412                 :                                     filter->in->size);
     413            2536 :       filter->in->wp = read_bytes;
     414            2536 :       if (read_bytes < filter->in->size)
     415                 :         {
     416            2277 :           ret = PDF_EEOF;
     417                 :         }
     418                 :     }
     419                 :   else
     420                 :     {
     421                 :       /* No backend */
     422            2423 :       ret = PDF_EEOF;
     423                 :     }
     424                 : 
     425            7438 :   return ret;
     426                 : }
     427                 : 
     428                 : /* End of pdf-stm-filter.c */

Generated by: LTP GCOV extension version 1.6