pdf-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [pdf-devel] Patch for Flate filter improved


From: gerel
Subject: Re: [pdf-devel] Patch for Flate filter improved
Date: Sun, 05 Oct 2008 08:13:48 -0700 (PDT)

Ok, this is the good one. (I hope)

##
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: address@hidden
# target_branch: file:///home/gerel/PROJECTS/libgnupdf/trunk/
# testament_sha1: 6a01bc7e33f07e93e645cb9c1b931c8d27291d6a
# timestamp: 2008-10-05 13:08:34 -0200
# base_revision_id: address@hidden
# 
# Begin patch
=== modified file 'ChangeLog'
--- ChangeLog   2008-10-04 18:44:47 +0000
+++ ChangeLog   2008-10-05 15:08:05 +0000
@@ -1,3 +1,23 @@
+2008-10-05  Gerardo E. Gidoni  <address@hidden>
+
+       * doc/gnupdf-tsd.texi: added flate filter tests.
+
+       * torture/unit/base/stm/pdf-stm-read.c: same.
+
+       * torture/unit/base/stm/pdf-stm-write.c: same.
+
+       * src/Makefile.am: added flate filter source files.
+
+       * src/base/pdf-stm-f-flate.c: adapted for new stream API.
+
+       * src/base/pdf-stm-f-flate.h: same.
+
+       * src/base/pdf-stm-filter.c: added flate filter.
+
+       * src/base/pdf-stm-filter.h: same.
+
+       * utils/pdf-filter.c: same.
+
 2008-10-04  Gerardo E. Gidoni  <address@hidden>
 
        * src/base/pdf-stm-f-rl.c: adapted to new filter API.

=== modified file 'doc/gnupdf-tsd.texi'
--- doc/gnupdf-tsd.texi 2008-09-28 14:00:42 +0000
+++ doc/gnupdf-tsd.texi 2008-10-05 15:08:05 +0000
@@ -277,6 +277,16 @@
 @end table
 @end deffn
 
+
address@hidden Test pdf_stm_read_009
+Create a memory-based reading stream and attach a flate filter
+decoder to it.
address@hidden @strong
address@hidden Success condition
+The decoded data should be correct.
address@hidden table
address@hidden deffn
+
 @node pdf_stm_read_char
 @subsubsection pdf_stm_read_char
 
@@ -405,6 +415,18 @@
 @end deffn
 
 
address@hidden Test pdf_stm_write_007
+Create a memory-based writing stream and attach a flate filter
+encoder to it.
address@hidden @strong
address@hidden Success condition
+The encoded data should be correct.
address@hidden table
address@hidden deffn
+
+
+
+
 @node Text Module
 @subsection Text Module
 

=== modified file 'src/Makefile.am'
--- src/Makefile.am     2008-09-27 22:28:27 +0000
+++ src/Makefile.am     2008-10-05 15:08:05 +0000
@@ -46,9 +46,9 @@
                      base/pdf-stm-f-ahex.h base/pdf-stm-f-ahex.c \
                      base/pdf-stm-f-rl.h base/pdf-stm-f-rl.c
 
-# if ZLIB
-#  STM_MODULE_SOURCES += base/pdf-stm-f-flate.c base/pdf-stm-f-flate.h
-#endif
+if ZLIB
+  STM_MODULE_SOURCES += base/pdf-stm-f-flate.c base/pdf-stm-f-flate.h
+endif
 
 TEXT_MODULE_SOURCES = base/pdf-text-context.c base/pdf-text-context.h \
                       base/pdf-text-encoding.c base/pdf-text-encoding.h \

=== modified file 'src/base/pdf-stm-f-flate.c'
--- src/base/pdf-stm-f-flate.c  2008-03-05 12:32:04 +0000
+++ src/base/pdf-stm-f-flate.c  2008-10-05 15:08:05 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/03/05 12:24:36 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-10-04 18:03:28 gerel"
  *
  *       File:         pdf-stm-f-flate.c
  *       Date:         Tue Jul 10 23:44:00 2007
@@ -26,172 +26,324 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <zlib.h>
 #include <pdf-alloc.h>
-#include <pdf-base.h>
+#include <pdf-hash.h>
 #include <pdf-stm-f-flate.h>
 
 
-static int pdf_stm_f_flate_encode (pdf_char_t *in, pdf_stm_pos_t in_size,
-                                   pdf_char_t **out, pdf_stm_pos_t *out_size);
-static int pdf_stm_f_flate_decode (pdf_char_t *in, pdf_stm_pos_t in_size,
-                                   pdf_char_t **out, pdf_stm_pos_t *out_size);
-
-int
-pdf_stm_f_flate_init (void **filter_data,
-                     void *conf_data)
-{
-  pdf_stm_f_flate_data_t *data;
-  pdf_stm_f_flate_conf_t conf;
-
-  data = (pdf_stm_f_flate_data_t *) filter_data;
-  conf = (pdf_stm_f_flate_conf_t) conf_data;
-
-  /* Create the private data storage */
-  *data =
-    (pdf_stm_f_flate_data_t) pdf_alloc (sizeof(struct pdf_stm_f_flate_data_s));
-  (*data)->mode = conf->mode;
-
-  return PDF_OK;
-}
-
-int
-pdf_stm_f_flate_apply (void *filter_data,
-                      pdf_char_t *in, pdf_stm_pos_t in_size,
-                      pdf_char_t **out, pdf_stm_pos_t *out_size)
-{
-  pdf_stm_f_flate_data_t data;
-
-  data = (pdf_stm_f_flate_data_t) filter_data;
-  switch (data->mode)
-    {
-    case PDF_STM_F_FLATE_MODE_ENCODE:
-      {
-        return pdf_stm_f_flate_encode (in, in_size, out, out_size);
-      }
-    case PDF_STM_F_FLATE_MODE_DECODE:
-      {
-        return pdf_stm_f_flate_decode (in, in_size, out, out_size);
-      }
-    default:
-      {
+static int deflate_inbuf (pdf_stm_f_flate_t st, pdf_stm_buffer_t out,
+                          int flush);
+static pdf_status_t deflate_inbuf_return (pdf_stm_f_flate_t st,
+                                          pdf_stm_buffer_t out,
+                                          pdf_bool_t finish_p);
+
+pdf_status_t
+pdf_stm_f_flateenc_init (pdf_hash_t params, void **state)
+{
+  pdf_status_t ret;
+  pdf_stm_f_flate_t filter_state;
+
+  filter_state = pdf_alloc (sizeof (struct pdf_stm_f_flate_s));
+
+  if (state == NULL)
+    {
+      ret = PDF_EBADDATA;
+    }
+  else if (filter_state == NULL)
+    {
+      ret = PDF_ENOMEM;
+    }
+  else
+    {
+      /* Initialize fields */
+      filter_state->stream.zalloc = Z_NULL;
+      filter_state->stream.zfree = Z_NULL;
+      filter_state->stream.opaque = Z_NULL;
+      filter_state->writing_p = PDF_FALSE;
+      filter_state->to_write = 0;
+      filter_state->incnt = 0;
+      filter_state->outcnt = 0;
+      filter_state->zret = Z_OK;
+
+      if (deflateInit (&(filter_state->stream), Z_DEFAULT_COMPRESSION) != Z_OK)
+        {
+          ret = PDF_ERROR;
+        }
+      else
+        {
+          *state = (void *) filter_state;
+          ret = PDF_OK;
+        }
+    }
+
+  return ret;
+}
+
+
+pdf_status_t
+pdf_stm_f_flatedec_init (pdf_hash_t params, void **state)
+{
+  pdf_status_t ret;
+  pdf_stm_f_flate_t filter_state;
+
+  filter_state = pdf_alloc (sizeof (struct pdf_stm_f_flate_s));
+
+  if (state == NULL)
+    {
+      ret = PDF_EBADDATA;
+    }
+  else if (filter_state == NULL)
+    {
+      ret = PDF_ENOMEM;
+    }
+  else
+    {
+      /* Initialize fields */
+      filter_state->stream.zalloc = Z_NULL;
+      filter_state->stream.zfree = Z_NULL;
+      filter_state->stream.opaque = Z_NULL;
+      filter_state->stream.avail_in = 0;
+      filter_state->stream.next_in = Z_NULL;
+      filter_state->writing_p = PDF_FALSE;
+      filter_state->to_write = 0;
+      filter_state->incnt = 0;
+      filter_state->outcnt = 0;
+      filter_state->zret = Z_OK;
+
+      if (inflateInit (&(filter_state->stream)) != Z_OK)
+        {
+          ret = PDF_ERROR;
+        }
+      else
+        {
+          *state = (void *) filter_state;
+          ret = PDF_OK;
+        }
+    }
+
+  return ret;
+
+}
+
+
+pdf_status_t
+pdf_stm_f_flateenc_apply (pdf_hash_t params, void *state, pdf_stm_buffer_t in,
+                          pdf_stm_buffer_t out, pdf_bool_t finish_p)
+{
+  pdf_stm_f_flate_t st;
+
+  st = (pdf_stm_f_flate_t) state;
+
+
+  /* Fill the input CHUNK  */
+  if (!st->writing_p)
+    {
+      while (st->incnt < PDF_STM_F_FLATE_CHUNK && !pdf_stm_buffer_eob_p(in))
+        {
+          st->inbuf[st->incnt] = in->data[in->rp];
+          st->incnt++;
+          in->rp++;
+        }
+      /* If more data may come and the input CHUNK has space, ask for it. */
+      if (!finish_p && st->incnt < PDF_STM_F_FLATE_CHUNK)
+        {
+          return PDF_ENINPUT;
+        }
+    }
+    
+  /* 
+   * Now we have the input CHUNK full or finish_p is set,
+   * we deflate and write to out.
+   */ 
+  return (deflate_inbuf_return (st, out, finish_p));
+}
+
+
+pdf_status_t
+pdf_stm_f_flatedec_apply (pdf_hash_t params, void *state, pdf_stm_buffer_t in,
+                          pdf_stm_buffer_t out, pdf_bool_t finish_p)
+{
+  pdf_stm_f_flate_t st;
+
+  st = (pdf_stm_f_flate_t) state;
+
+  /* Fill the input CHUNK */
+  if (!st->writing_p)
+    {
+      while (st->incnt < PDF_STM_F_FLATE_CHUNK && !pdf_stm_buffer_eob_p(in))
+        {
+          st->inbuf[st->incnt] = in->data[in->rp];
+          st->incnt++;
+          in->rp++;
+        }
+    }
+  else
+    {
+      /* 
+       * Not nice, but keeps the writing process code clear.
+       * Notice that the labeled code is inside a while loop,
+       * so I feel that avoiding this goto won't bring us better code.
+       */
+      goto writing;
+    }
+
+  if (st->incnt == 0)
+    {
+      return PDF_ENINPUT;
+    }
+
+  /* we inflate and write to out */
+  st->stream.avail_in = st->incnt;
+  st->stream.next_in = st->inbuf;
+  do {
+    st->stream.avail_out = PDF_STM_F_FLATE_CHUNK;
+    st->stream.next_out = st->outbuf;
+    st->outcnt = 0;
+
+    st->zret = inflate(&(st->stream), Z_NO_FLUSH);
+    if (st->zret == Z_STREAM_ERROR || st->zret == Z_NEED_DICT ||
+        st->zret == Z_DATA_ERROR || st->zret == Z_MEM_ERROR)
+      {
+        /* should not be reached */
+        inflateEnd(&(st->stream));
         return PDF_ERROR;
       }
-    }
-  
-  /* Not reached */
-}
-
-int
-pdf_stm_f_flate_dealloc (void **filter_data)
-{
-  pdf_stm_f_flate_data_t *data;
-
-  data = (pdf_stm_f_flate_data_t *) filter_data;
-  pdf_dealloc (*data);
-
-  return PDF_OK;
-}
+
+    st->to_write = PDF_STM_F_FLATE_CHUNK - st->stream.avail_out;
+
+  writing:
+    while (st->outcnt < st->to_write && !pdf_stm_buffer_full_p(out))
+      {
+        out->data[out->wp] = st->outbuf[st->outcnt];
+        out->wp++;
+        st->outcnt++;
+      }
+    if (pdf_stm_buffer_full_p(out))
+      {
+        st->writing_p = PDF_TRUE;
+        return PDF_ENOUTPUT;
+      }
+  } while (st->stream.avail_out == 0);
+
+  if (st->zret == Z_STREAM_END)
+    {
+      return PDF_EEOF;
+    }
+  /* the input CHUNK now is empty, if needed, ask for input */
+  st->writing_p = PDF_FALSE;
+  st->incnt = 0;
+  if (pdf_stm_buffer_eob_p(in))
+    {
+      return PDF_ENINPUT;
+    }
+
+  return PDF_OK;
+}
+
+
+
+pdf_status_t
+pdf_stm_f_flatedec_dealloc_state (void *state)
+{
+  pdf_stm_f_flate_t st = state;
+  inflateEnd(&(st->stream));
+  pdf_dealloc (state);
+  return PDF_OK;
+}
+
+pdf_status_t
+pdf_stm_f_flateenc_dealloc_state (void *state)
+{
+  pdf_dealloc (state);
+  return PDF_OK;
+}
+
 
 /* Private functions */
 
 static int
-pdf_stm_f_flate_encode (pdf_char_t *in, 
-                        pdf_stm_pos_t in_size,
-                        pdf_char_t **out,
-                        pdf_stm_pos_t *out_size)
-{
-  unsigned long compressed_bound;
+deflate_inbuf (pdf_stm_f_flate_t st, pdf_stm_buffer_t out, int flush)
+{
+  if (st->writing_p)
+    {
+      /* 
+       * Not nice, but keeps the writing process code clear.
+       * Notice that the labeled code is inside a while loop,
+       * so I feel that avoiding this goto won't bring us better code.
+       */
+      goto writing;
+    }
+
+  st->stream.avail_in = st->incnt;
+  st->stream.next_in = st->inbuf;
+  do {
+    st->stream.avail_out = PDF_STM_F_FLATE_CHUNK;
+    st->stream.next_out = st->outbuf;
+    st->outcnt = 0;
+
+    st->zret = deflate(&(st->stream), flush);
+    if (st->zret == Z_STREAM_ERROR)
+      {
+        /* should not be reached */
+        deflateEnd (&(st->stream));
+        return -1;
+      }
+
+    st->to_write = PDF_STM_F_FLATE_CHUNK - st->stream.avail_out;
+
+  writing:
+
+    while (st->outcnt < st->to_write && !pdf_stm_buffer_full_p(out))
+      {
+        out->data[out->wp++] = st->outbuf[st->outcnt];
+        st->outcnt++;
+      }
+    if (pdf_stm_buffer_full_p(out))
+      {
+        st->writing_p = PDF_TRUE;
+        return 1;
+      }
+  } while (st->stream.avail_out == 0);
+
+  st->writing_p = PDF_FALSE;
+  return 0;
+}
+
+
+static pdf_status_t
+deflate_inbuf_return (pdf_stm_f_flate_t st, pdf_stm_buffer_t out,
+                      pdf_bool_t finish_p)
+{
   int ret;
 
-  /* Allocate memory for destination buffer */
-  compressed_bound = compressBound (in_size);
-  *out_size = compressed_bound;
-  *out = (pdf_char_t *) pdf_alloc (*out_size);
-
-  /* Compress input */
-  ret = compress (*out, 
-                  (unsigned long *) out_size,
-                  in,
-                  in_size);
-
-  if (ret == Z_OK)
-    {
-      /* Adjust memory to really used  and return */
-      *out = (pdf_char_t *) pdf_realloc (*out,
-                                         *out_size);
+  if (finish_p)
+    {
+      ret = deflate_inbuf(st, out, Z_FINISH);
+    }
+  else
+    {
+      ret = deflate_inbuf(st, out, Z_NO_FLUSH);
+    }
+
+  if (ret < 0)
+    {
+      return PDF_ERROR;
+    }
+  else if (ret > 0)
+    {
+      return PDF_ENOUTPUT;
+    }
+  else if (finish_p)
+    {
+      deflateEnd (&(st->stream));
+      return PDF_EEOF;
+    }
+  else
+    {
+      /* the input CHUNK now is empty */
+      st->incnt = 0;
       return PDF_OK;
     }
-  else
-    {
-      /* Z_MEM_ERROR or Z_BUF_ERROR happened.  In any case, return
-         reporting that the filter application failed. */
-      return PDF_FALSE;
-    }
-
-  /* Not reached */
-}
-
-#define CHUNK 16384
-
-static int
-pdf_stm_f_flate_decode (pdf_char_t *in,
-                        pdf_stm_pos_t in_size,
-                        pdf_char_t **out,
-                        pdf_stm_pos_t *out_size)
-{
-  z_stream zstm;
-  int ret;
-  pdf_char_t out_aux[16384];
-  pdf_stm_pos_t nchunks;
-
-  zstm.zalloc = Z_NULL;
-  zstm.zfree = Z_NULL;
-  zstm.opaque = Z_NULL;
-  zstm.avail_in = in_size;
-  zstm.next_in = in;
-
-  inflateInit (&zstm);
-
-  *out_size = 0;
-  *out = NULL;
-  nchunks = 0;
-  do
-    {
-      zstm.avail_out = CHUNK;
-      zstm.next_out = out_aux;
-      
-      ret = inflate (&zstm, Z_NO_FLUSH);
-
-      switch (ret)
-        {
-        case Z_NEED_DICT:
-        case Z_DATA_ERROR:
-        case Z_MEM_ERROR:
-          {
-            goto error;
-          }
-        }
-          
-      *out_size =  *out_size + (CHUNK - zstm.avail_out);
-      *out = (pdf_char_t *) pdf_realloc (*out,
-                                         *out_size);
-
-      memcpy (*out + (nchunks * CHUNK),
-              out_aux,
-              CHUNK - zstm.avail_out);
-
-      nchunks++;
-
-    } while (ret != Z_STREAM_END);
-
-  ret = inflateEnd (&zstm);
-  
-  return PDF_OK;
-
- error:
-  (void) inflateEnd (&zstm);
-  return PDF_ERROR;
 }
 
 

=== modified file 'src/base/pdf-stm-f-flate.h'
--- src/base/pdf-stm-f-flate.h  2008-02-11 01:11:25 +0000
+++ src/base/pdf-stm-f-flate.h  2008-10-05 15:08:05 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/02/11 01:04:11 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-10-01 18:16:15 gerel"
  *
  *       File:         pdf-stm-f-flate.h
  *       Date:         Tue Jul 10 23:39:27 2007
@@ -27,43 +27,53 @@
 #define PDF_STM_F_FLATE_H
 
 #include <config.h>
-#include <pdf-base.h>
-
-/* Filter configuration */
-
-/* BEGIN PUBLIC */
-
-enum pdf_stm_f_flate_mode_t
-{
-  PDF_STM_F_FLATE_MODE_ENCODE,
-  PDF_STM_F_FLATE_MODE_DECODE
-};
-
-/* END PUBLIC */
-
-struct pdf_stm_f_flate_conf_s
-{
-  int mode;
-};
-
-typedef struct pdf_stm_f_flate_conf_s *pdf_stm_f_flate_conf_t;
-
-/* Private data */
-
-struct pdf_stm_f_flate_data_s
-{
-  int mode;
-};
-
-typedef struct pdf_stm_f_flate_data_s *pdf_stm_f_flate_data_t;
+#include <pdf-hash.h>
+#include <pdf-stm-buffer.h>
+#include <zlib.h>
+
+
+
+ /* 
+  * As read in the zlib documentation, our cache size must be at least 0.1%
+  * larger than the CHUNK size, plus 12 bytes.
+  * We assume that our cache size is of 4096 bytes.
+  */
+#define PDF_STM_F_FLATE_CHUNK 1024
+
+struct pdf_stm_f_flate_s
+{
+  z_stream stream;
+  int zret;
+  pdf_size_t incnt, outcnt, to_write;
+  pdf_bool_t writing_p;
+  pdf_char_t inbuf[PDF_STM_F_FLATE_CHUNK], outbuf[PDF_STM_F_FLATE_CHUNK];
+};
+
+typedef struct pdf_stm_f_flate_s * pdf_stm_f_flate_t;
+
 
 /* Filter API implementation */
 
-int pdf_stm_f_flate_init (void **filter_data, void *conf_data);
-int pdf_stm_f_flate_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_flate_dealloc (void **filter_data);
+pdf_status_t pdf_stm_f_flatedec_init (pdf_hash_t params,
+                                   void **state);
+
+pdf_status_t pdf_stm_f_flatedec_apply (pdf_hash_t params,
+                                    void *state,
+                                    pdf_stm_buffer_t in,
+                                    pdf_stm_buffer_t out,
+                                    pdf_bool_t finish_p);
+
+pdf_status_t pdf_stm_f_flateenc_init (pdf_hash_t params,
+                                   void **state);
+
+pdf_status_t pdf_stm_f_flateenc_apply (pdf_hash_t params,
+                                    void *state,
+                                    pdf_stm_buffer_t in,
+                                    pdf_stm_buffer_t out,
+                                    pdf_bool_t finish_p);
+
+pdf_status_t pdf_stm_f_flatedec_dealloc_state (void *state);
+pdf_status_t pdf_stm_f_flateenc_dealloc_state (void *state);
 
 
 #endif /* pdf_stm_f_flate.h */

=== modified file 'src/base/pdf-stm-filter.c'
--- src/base/pdf-stm-filter.c   2008-10-04 12:31:11 +0000
+++ src/base/pdf-stm-filter.c   2008-10-05 15:08:05 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/10/04 04:35:11 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-10-05 12:59:17 gerel"
  *
  *       File:         pdf-stm-filter.c
  *       Date:         Thu Jun 12 22:13:31 2008
@@ -97,6 +97,20 @@
         new->impl.dealloc_state_fn = pdf_stm_f_rldec_dealloc_state;
         break;
       }
+    case PDF_STM_FILTER_FLATE_ENC:
+      {
+        new->impl.init_fn = pdf_stm_f_flateenc_init;
+        new->impl.apply_fn = pdf_stm_f_flateenc_apply;
+        new->impl.dealloc_state_fn = pdf_stm_f_flateenc_dealloc_state;
+        break;
+      }
+    case PDF_STM_FILTER_FLATE_DEC:
+      {
+        new->impl.init_fn = pdf_stm_f_flatedec_init;
+        new->impl.apply_fn = pdf_stm_f_flatedec_apply;
+        new->impl.dealloc_state_fn = pdf_stm_f_flatedec_dealloc_state;
+        break;
+      }
     default:
       {
         /* Shall not be reached, but makes the compiler happy */

=== modified file 'src/base/pdf-stm-filter.h'
--- src/base/pdf-stm-filter.h   2008-10-04 12:31:11 +0000
+++ src/base/pdf-stm-filter.h   2008-10-05 15:08:05 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/10/04 04:34:08 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-10-05 12:59:37 gerel"
  *
  *       File:         pdf-stm-filter.h
  *       Date:         Thu Jun 12 22:05:06 2008
@@ -35,6 +35,7 @@
 #include <pdf-stm-f-null.h>
 #include <pdf-stm-f-ahex.h>
 #include <pdf-stm-f-rl.h>
+#include <pdf-stm-f-flate.h>
 
 /* BEGIN PUBLIC */
 
@@ -45,7 +46,10 @@
   PDF_STM_FILTER_AHEX_ENC,
   PDF_STM_FILTER_AHEX_DEC,
   PDF_STM_FILTER_RL_ENC,
-  PDF_STM_FILTER_RL_DEC
+  PDF_STM_FILTER_RL_DEC,
+  PDF_STM_FILTER_FLATE_ENC,
+  PDF_STM_FILTER_FLATE_DEC
+
 };
 
 /* Filter implementation */

=== modified file 'torture/unit/base/stm/pdf-stm-read.c'
--- torture/unit/base/stm/pdf-stm-read.c        2008-10-04 18:44:47 +0000
+++ torture/unit/base/stm/pdf-stm-read.c        2008-10-05 15:08:05 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "2008-10-04 15:42:24 gerel"
+/* -*- mode: C -*- Time-stamp: "2008-10-05 13:07:53 gerel"
  *
  *       File:         pdf-stm-read.c
  *       Date:         Sat Sep 20 15:20:17 2008
@@ -471,6 +471,7 @@
 }
 END_TEST
 
+
 /*
  * Test: pdf_stm_read_008
  * Description:
@@ -536,6 +537,83 @@
 }
 END_TEST
 
+/*
+ * Test: pdf_stm_read_009
+ * Description:
+ *   Create a memory-based reading stream and attach a flate filter
+ *   decoder to it.
+ * Success condition:
+ *   The decoded data should be correct.
+ */
+START_TEST (pdf_stm_read_009)
+{
+  pdf_status_t ret;
+  pdf_hash_t params;
+  pdf_stm_t stm;
+  pdf_size_t buf_size, total=1059,read;
+  pdf_char_t *buf, *decoded=
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990";
+  pdf_char_t *dataux, *encoded =
+    "\x78\x9c\x33\x34\x32\x32\x36\x36\x36\x01\x02\x53\x10\x30\x03\x03"
+    "\x73\x08\xb0\x80\x02\x4b\x18\x30\x30\x1c\x55\x3d\xaa\x7a\x54\xf5"
+    "\x88\x52\xcd\x00\x00\xe1\x0b\xdf\xfc";
+
+  /* Writing stream */
+  /* Create a memory buffer */
+  buf_size = 2000;
+  buf = pdf_alloc (buf_size);
+  fail_if(buf == NULL);
+  /* Create the stream */
+  ret = pdf_stm_mem_new (encoded,
+                         41,
+                         1,
+                         PDF_STM_READ,
+                         &stm);
+  fail_if(ret != PDF_OK);
+  /* Create the filter */
+  fail_if (pdf_stm_install_filter (stm, PDF_STM_FILTER_FLATE_DEC, params) !=
+           PDF_OK);
+
+  read = 0;
+  total = 1059;
+  dataux = buf;
+  while (total > 0)
+    {
+      read = pdf_stm_read (stm, dataux, total);
+      dataux = dataux + read;
+      total -= read;
+    }
+
+  fail_if (memcmp (buf, decoded, 1059) != 0);
+  /* Destroy the stream */
+  pdf_stm_destroy (stm);
+  pdf_dealloc (buf);
+
+}
+END_TEST
+
 
 /*
  * Test case creation function
@@ -553,6 +631,7 @@
   tcase_add_test(tc, pdf_stm_read_006);
   tcase_add_test(tc, pdf_stm_read_007);
   tcase_add_test(tc, pdf_stm_read_008);
+  tcase_add_test(tc, pdf_stm_read_009);
 
   return tc;
 }

=== modified file 'torture/unit/base/stm/pdf-stm-write.c'
--- torture/unit/base/stm/pdf-stm-write.c       2008-10-04 18:44:47 +0000
+++ torture/unit/base/stm/pdf-stm-write.c       2008-10-05 15:08:05 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "2008-10-04 15:38:46 gerel"
+/* -*- mode: C -*- Time-stamp: "2008-10-05 13:06:54 gerel"
  *
  *       File:         pdf-stm-write.c
  *       Date:         Sun Sep 21 16:37:27 2008
@@ -347,6 +347,86 @@
 }
 END_TEST
 
+
+/*
+ * Test: pdf_stm_write_007
+ * Description:
+ *   Create a memory-based writing stream and attach a flate filter
+ *   encoder to it.
+ * Success condition:
+ *   The encoded data should be correct.
+ */
+START_TEST (pdf_stm_write_007)
+{
+  pdf_status_t ret;
+  pdf_hash_t params;
+  pdf_stm_t stm;
+  pdf_size_t buf_size, total,written;
+  pdf_char_t *buf, *decoded=
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990" \
+    "1223334444555556666667777777888888889999999990";
+  pdf_char_t *dataux, *encoded =
+    "\x78\x9c\x33\x34\x32\x32\x36\x36\x36\x01\x02\x53\x10\x30\x03\x03"
+    "\x73\x08\xb0\x80\x02\x4b\x18\x30\x30\x1c\x55\x3d\xaa\x7a\x54\xf5"
+    "\x88\x52\xcd\x00\x00\xe1\x0b\xdf\xfc";
+
+  /* Writing stream */
+  /* Create a memory buffer */
+  buf_size = 100;
+  buf = pdf_alloc (buf_size);
+  fail_if(buf == NULL);
+  /* Create the stream */
+  ret = pdf_stm_mem_new (buf,
+                         buf_size,
+                         1,
+                         PDF_STM_WRITE,
+                         &stm);
+  fail_if(ret != PDF_OK);
+  /* Create the filter */
+  fail_if (pdf_stm_install_filter (stm, PDF_STM_FILTER_FLATE_ENC, params) !=
+           PDF_OK);
+
+  written = 0;
+  total = 1059;
+  dataux = decoded;
+  while (total > 0)
+    {
+      written = pdf_stm_write (stm, dataux, total);
+      dataux = dataux + written;
+      total -= written;
+    }
+  pdf_stm_flush (stm, PDF_TRUE);
+
+  fail_if (memcmp (buf, encoded, 41) != 0);
+  /* Destroy the stream */
+  pdf_stm_destroy (stm);
+  pdf_dealloc (buf);
+
+}
+END_TEST
+
+
 /*
  * Test case creation function
  */
@@ -361,6 +441,7 @@
   tcase_add_test(tc, pdf_stm_write_004);
   tcase_add_test(tc, pdf_stm_write_005);
   tcase_add_test(tc, pdf_stm_write_006);
+  tcase_add_test(tc, pdf_stm_write_007);
   
   return tc;
 }

=== modified file 'utils/pdf-filter.c'
--- utils/pdf-filter.c  2008-10-04 18:10:03 +0000
+++ utils/pdf-filter.c  2008-10-05 15:08:05 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/10/04 20:05:35 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-10-05 12:57:40 gerel"
  *
  *       File:         pdf-filter.c
  *       Date:         Tue Jul 10 18:42:07 2007
@@ -335,10 +335,30 @@
 #ifdef HAVE_LIBZ
         case FLATEDEC_FILTER_ARG:
           {
+            ret = pdf_hash_new (NULL, &filter_params);
+            if (ret != PDF_OK)
+              {
+                pdf_error (ret, stderr, "while creating the flatedec filter 
parameters hash table");
+                exit (1);
+              }
+
+            pdf_stm_install_filter (stm,
+                                    PDF_STM_FILTER_FLATE_DEC,
+                                    filter_params);
             break;
           }
         case FLATEENC_FILTER_ARG:
           {
+            ret = pdf_hash_new (NULL, &filter_params);
+            if (ret != PDF_OK)
+              {
+                pdf_error (ret, stderr, "while creating the flateenc filter 
parameters hash table");
+                exit (1);
+              }
+
+            pdf_stm_install_filter (stm,
+                                    PDF_STM_FILTER_FLATE_ENC,
+                                    filter_params);
             break;
           }
 #endif /* HAVE_LIBZ */

# Begin bundle
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


###

-gerel




reply via email to

[Prev in Thread] Current Thread [Next in Thread]