LTP GCOV extension - code coverage report
Current view: directory - src/base - pdf-stm-f-rl.c
Test: libgnupdf.info
Date: 2010-07-31 Instrumented lines: 113
Code covered: 86.7 % Executed lines: 98

       1                 : /* -*- mode: C -*-
       2                 :  *
       3                 :  *       File:         pdf-stm-f-rl.c
       4                 :  *       Date:         Sun Jul 15 22:01:18 2007
       5                 :  *
       6                 :  *       GNU PDF Library - RunLength encoder/decoder
       7                 :  *
       8                 :  */
       9                 : 
      10                 : /* Copyright (C) 2007, 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 <string.h>
      29                 : #include <stdio.h>
      30                 : 
      31                 : #include <pdf-alloc.h>
      32                 : #include <pdf-stm-f-rl.h>
      33                 : 
      34                 : 
      35                 : static int encode_rl_char (pdf_stm_f_rl_t st, pdf_buffer_t out);
      36                 : static int decode_rl_char (pdf_stm_f_rl_t st, pdf_buffer_t out);
      37                 : static int copy_next_bytes (pdf_stm_f_rl_t st, pdf_buffer_t in,
      38                 :                             pdf_buffer_t out);
      39                 : 
      40                 : 
      41                 : pdf_status_t
      42                 : pdf_stm_f_rlenc_init (pdf_hash_t params, void **state)
      43               2 : {
      44                 :   pdf_status_t ret;
      45                 :   pdf_stm_f_rl_t filter_state;
      46                 : 
      47               2 :   filter_state = pdf_alloc (sizeof (struct pdf_stm_f_rl_s));
      48                 : 
      49               2 :   if (state == NULL)
      50                 :     {
      51               0 :       ret = PDF_EBADDATA;
      52                 :     }
      53               2 :   else if (filter_state == NULL)
      54                 :     {
      55               0 :       ret = PDF_ENOMEM;
      56                 :     }
      57                 :   else
      58                 :     {
      59                 :       /* Initialize fields */
      60               2 :       filter_state->curchar = 0;
      61               2 :       filter_state->rlchar = 0;
      62               2 :       filter_state->run_p = PDF_FALSE;
      63               2 :       filter_state->rl = -1;
      64               2 :       filter_state->dec_p = PDF_FALSE;;
      65               2 :       filter_state->dec_count = 0;
      66               2 :       filter_state->enc_p = PDF_STM_F_RL_NONE;
      67                 : 
      68               2 :       *state = (void *) filter_state;
      69               2 :       ret = PDF_OK;
      70                 :     }
      71                 : 
      72               2 :   return ret;
      73                 : }
      74                 : 
      75                 : 
      76                 : pdf_status_t
      77                 : pdf_stm_f_rldec_init (pdf_hash_t params, void **state)
      78               1 : {
      79               1 :   return pdf_stm_f_rlenc_init (params,state);
      80                 : }
      81                 : 
      82                 : 
      83                 : pdf_status_t
      84                 : pdf_stm_f_rlenc_apply (pdf_hash_t params, void * state, pdf_buffer_t in,
      85                 :                        pdf_buffer_t out, pdf_bool_t finish_p)
      86             112 : {
      87                 :   pdf_stm_f_rl_t st;
      88                 : 
      89             112 :   st = (pdf_stm_f_rl_t) state;
      90                 : 
      91             279 :   while (!pdf_buffer_eob_p (in))
      92                 :     {
      93              64 :       st->curchar = in->data[in->rp];
      94                 : 
      95                 :       /* we're not encoding any character yet */
      96              64 :       if (!st->run_p)
      97                 :         {
      98              10 :           st->rlchar = st->curchar;
      99              10 :           st->run_p = PDF_TRUE;
     100              10 :           st->rl++; 
     101              10 :           in->rp++;
     102                 :         }
     103                 :       /* we're encoding some character now */
     104              90 :       else if (st->curchar == st->rlchar && st->rl < 127)
     105                 :         {
     106              36 :           st->rl++;
     107              36 :           in->rp++;
     108                 :         }
     109                 :       /* 
     110                 :        * the rl code is too long or the rl char is different,
     111                 :        * so we write what we encoded so far.
     112                 :        */
     113                 :       else
     114                 :         {
     115              18 :           if (encode_rl_char (st, out) < 0)
     116                 :             {
     117               9 :               return PDF_ENOUTPUT;
     118                 :             }
     119               9 :           st->rl=-1;
     120               9 :           st->run_p = PDF_FALSE;
     121                 :         }
     122                 :     }
     123                 : 
     124                 :   /* 
     125                 :    * we may have finished with some history, we save it if needed,
     126                 :    * then we add the EOD.
     127                 :    */
     128             103 :   if (finish_p)
     129                 :     {
     130               3 :       if (st->run_p)
     131                 :         {
     132               2 :           if (encode_rl_char (st, out) < 0)
     133                 :             {
     134                 :               /* Should not be reached */
     135               1 :               return PDF_ENOUTPUT;
     136                 :             }
     137               1 :           st->rl=-1;
     138               1 :           st->run_p = PDF_FALSE;
     139                 :         }
     140               2 :       if (pdf_buffer_full_p (out))
     141                 :         {
     142                 :           /* Should not be reached */
     143               1 :           return PDF_ENOUTPUT;
     144                 :         }
     145                 :       /* Insert EOD marker */
     146               1 :       out->data[out->wp++] = 128;
     147               1 :       return PDF_EEOF;
     148                 :     }
     149                 : 
     150             100 :   return PDF_ENINPUT;
     151                 : }
     152                 : 
     153                 : 
     154                 : pdf_status_t
     155                 : pdf_stm_f_rlenc_dealloc_state (void *state)
     156               1 : {
     157               1 :   pdf_dealloc (state);
     158               1 :   return PDF_OK;
     159                 : }
     160                 : 
     161                 : pdf_status_t
     162                 : pdf_stm_f_rldec_apply (pdf_hash_t params, void *state, pdf_buffer_t in,
     163                 :                        pdf_buffer_t out, pdf_bool_t finish_p)
     164              57 : {
     165                 :   pdf_stm_f_rl_t st;
     166                 :   pdf_status_t copied;
     167                 : 
     168              57 :   st = (pdf_stm_f_rl_t) state;
     169                 : 
     170             134 :   while (!pdf_buffer_eob_p (in))
     171                 :     {
     172              56 :       st->curchar = in->data[in->rp];
     173                 : 
     174                 :       /* we're not decoding any character yet */
     175              56 :       if (!st->run_p)
     176                 :         {
     177              10 :           st->rlchar = st->curchar;
     178              10 :           st->run_p = PDF_TRUE;
     179              10 :           in->rp++;
     180                 :         }
     181                 :       /* copy the following 1 to 128 bytes literally */
     182              46 :       else if (st->rlchar < 128)
     183                 :         {
     184               2 :           copied = copy_next_bytes (st, in, out);
     185                 :           if (copied < 0)
     186                 :             {
     187                 :               return PDF_ENOUTPUT;
     188                 :             }
     189               2 :           else if (copied > 0)
     190                 :             {
     191               0 :               return PDF_ENINPUT;
     192                 :             }
     193               2 :           st->run_p = PDF_FALSE;
     194                 :         }
     195                 :       /* copy the next char 257 - length (2 to 128) times */
     196              44 :       else if (st->rlchar > 128)
     197                 :         {
     198              44 :           if (decode_rl_char (st, out) < 0)
     199                 :             {
     200              36 :               return PDF_ENOUTPUT;
     201                 :             }
     202               8 :           st->run_p = PDF_FALSE;
     203               8 :           in->rp++;
     204                 :         }
     205                 :       /* EOD mark */
     206                 :       else
     207                 :         {
     208               0 :           st->run_p = PDF_FALSE;
     209               0 :           return PDF_EEOF;
     210                 :         }
     211                 :     }
     212                 : 
     213              21 :   return PDF_ENINPUT;
     214                 : }
     215                 : 
     216                 : pdf_status_t
     217                 : pdf_stm_f_rldec_dealloc_state (void *state)
     218               1 : {
     219               1 :   pdf_dealloc (state);
     220               1 :   return PDF_OK;
     221                 : }
     222                 : 
     223                 : /* Private functions */
     224                 : 
     225                 : static int
     226                 : encode_rl_char (pdf_stm_f_rl_t st, pdf_buffer_t out)
     227              20 : {
     228              20 :   if (st->enc_p == PDF_STM_F_RL_NONE)
     229                 :     {
     230              10 :       if (pdf_buffer_full_p (out))
     231                 :         {
     232               0 :           return -1;
     233                 :         }
     234              10 :       out->data[out->wp++] = (st->rl == 0) ? 0 : 256 - st->rl;    
     235              10 :       st->enc_p = PDF_STM_F_RL_WRL;
     236                 :     }
     237                 : 
     238              20 :   if (st->enc_p == PDF_STM_F_RL_WRL)
     239                 :     {
     240              20 :       if (pdf_buffer_full_p (out))
     241                 :         {
     242              10 :           return -1;
     243                 :         }
     244              10 :       out->data[out->wp++] = st->rlchar;
     245              10 :       st->enc_p = PDF_STM_F_RL_NONE;
     246                 :     }
     247                 : 
     248              10 :   return 0;
     249                 : }
     250                 : 
     251                 : 
     252                 : static int
     253                 : decode_rl_char (pdf_stm_f_rl_t st, pdf_buffer_t out)
     254                 : {
     255              44 :   if (!st->dec_p)
     256                 :     {
     257               8 :       st->dec_count = 257 - st->rlchar;
     258               8 :       st->dec_p = PDF_TRUE;
     259                 :     }
     260                 : 
     261              88 :   while (st->dec_count > 0)
     262                 :     {
     263              80 :       if (pdf_buffer_full_p (out))
     264                 :         {
     265              36 :           return -1;
     266                 :         }
     267              44 :       out->data[out->wp++] = st->curchar;
     268              44 :       st->dec_count--;
     269                 :     }
     270                 : 
     271               8 :   st->dec_p = PDF_FALSE;
     272               8 :   return 0;
     273                 : }
     274                 : 
     275                 : 
     276                 : static int
     277                 : copy_next_bytes (pdf_stm_f_rl_t st, pdf_buffer_t in, pdf_buffer_t out)
     278                 : {
     279               2 :   if (!st->dec_p)
     280                 :     {
     281               2 :       if (pdf_buffer_full_p (out))
     282                 :         {
     283               0 :           return -1;
     284                 :         }
     285               2 :       st->dec_count = st->rlchar + 1;
     286               2 :       st->dec_p = PDF_TRUE;
     287               2 :       out->data[out->wp++] = st->curchar;
     288               2 :       in->rp++;
     289               2 :       st->dec_count--;
     290                 :     }
     291                 : 
     292               2 :   while (st->dec_count > 0)
     293                 :     {
     294               0 :       if (pdf_buffer_eob_p (in))
     295                 :         {
     296               0 :           return 1;
     297                 :         }
     298               0 :       else if (pdf_buffer_full_p (out))
     299                 :         {
     300               0 :           return -1;
     301                 :         }
     302               0 :       out->data[out->wp] = in->data[in->rp];
     303               0 :       out->wp++;
     304               0 :       in->rp++;
     305               0 :       st->dec_count--;
     306                 :     }
     307                 : 
     308               2 :   st->dec_p = PDF_FALSE;
     309               2 :   return 0;
     310                 : }
     311                 : 
     312                 : 
     313                 : /* End of pdf_stm_f_rl.c */

Generated by: LTP GCOV extension version 1.6