changed pdf_calloc() to take two args like ordinary calloc(). added pdf_stream_write_bits() and pdf_stream_flush_bits().

Fri, 21 Feb 2003 10:49:11 +0000

author
eric
date
Fri, 21 Feb 2003 10:49:11 +0000
changeset 67
7add7411c1c2
parent 66
6e0551b59dba
child 68
cba49c5dbaa4

changed pdf_calloc() to take two args like ordinary calloc(). added pdf_stream_write_bits() and pdf_stream_flush_bits().

bitblt_g4.c file | annotate | diff | revisions
pdf.c file | annotate | diff | revisions
pdf_g4.c file | annotate | diff | revisions
pdf_prim.c file | annotate | diff | revisions
pdf_prim.h file | annotate | diff | revisions
pdf_util.c file | annotate | diff | revisions
pdf_util.h file | annotate | diff | revisions
     1.1 diff -r 6e0551b59dba -r 7add7411c1c2 bitblt_g4.c
     1.2 --- a/bitblt_g4.c	Fri Feb 21 09:25:47 2003 +0000
     1.3 +++ b/bitblt_g4.c	Fri Feb 21 10:49:11 2003 +0000
     1.4 @@ -4,7 +4,7 @@
     1.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
     1.6   *
     1.7   * PDF routines
     1.8 - * $Id: bitblt_g4.c,v 1.5 2003/02/21 01:25:47 eric Exp $
     1.9 + * $Id: bitblt_g4.c,v 1.6 2003/02/21 02:49:11 eric Exp $
    1.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    1.11   *
    1.12   * This program is free software; you can redistribute it and/or modify
    1.13 @@ -27,6 +27,7 @@
    1.14  #include <stdbool.h>
    1.15  #include <stdint.h>
    1.16  #include <stdio.h>
    1.17 +#include <stdlib.h>
    1.18  #include <string.h>
    1.19  
    1.20  
    1.21 @@ -37,6 +38,9 @@
    1.22  #include "pdf_private.h"
    1.23  
    1.24  
    1.25 +#define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0)
    1.26 +
    1.27 +
    1.28  struct pdf_g4_image
    1.29  {
    1.30    double width, height;
    1.31 @@ -94,28 +98,48 @@
    1.32  {
    1.33    struct pdf_g4_image *image = app_data;
    1.34  
    1.35 -#if 0
    1.36 -  pdf_stream_write_data (pdf_file, stream, image->data, image->len);
    1.37 -#else
    1.38 -  unsigned long row = 0;
    1.39 -  word_type *ref;
    1.40 -  word_type *raw;
    1.41 +  uint32_t row;
    1.42 +
    1.43 +  /* reference (previous) row */
    1.44 +  uint32_t *ref_runs = pdf_calloc (image->Columns, sizeof (uint32_t));
    1.45 +  uint32_t ref_run_count;
    1.46  
    1.47 -  ref = NULL;
    1.48 -  raw = image->bitmap->bits;
    1.49 +  /* row being converted */
    1.50 +  uint32_t *row_runs = pdf_calloc (image->Columns, sizeof (uint32_t));
    1.51 +  uint32_t row_run_count;
    1.52 +
    1.53 +  /* initialize reference row - all white */
    1.54 +  ref_runs [0] = image->Columns;
    1.55 +  ref_run_count = 0;
    1.56  
    1.57 -  while (row < image->Rows)
    1.58 +  for (row = image->bitmap->rect.min.y;
    1.59 +       row < image->bitmap->rect.max.y;
    1.60 +       row++)
    1.61      {
    1.62 -      pdf_stream_write_data (pdf_file, stream, (uint8_t *) raw,
    1.63 -			     image->bitmap->row_words * sizeof (word_type));
    1.64 +      row_run_count = get_row_run_lengths (image->bitmap,
    1.65 +					   row,
    1.66 +					   image->bitmap->rect.min.x,
    1.67 +					   image->bitmap->rect.max.x - 1,
    1.68 +					   image->Columns,  /* max_runs */
    1.69 +					   row_runs);
    1.70 +      pdf_assert (row_run_count > 0);
    1.71 +
    1.72 +      /* $$$ G4 encode the runs here */
    1.73  
    1.74 -      row++;
    1.75 -      ref = raw;
    1.76 -      raw += image->bitmap->row_words;
    1.77 +      /* pdf_stream_write_data (pdf_file, stream, image->data, image->len); */
    1.78 +
    1.79 +      SWAP (uint32_t *, row_runs, ref_runs);
    1.80 +      ref_run_count = row_run_count;
    1.81      }
    1.82 +
    1.83 +  
    1.84    /* $$$ generate and write EOFB code */
    1.85 -  /* $$$ flush any remaining buffered bits */
    1.86 -#endif
    1.87 +  pdf_stream_write_bits (pdf_file, stream, 24, 0x001001);
    1.88 +
    1.89 +  pdf_stream_flush_bits (pdf_file, stream);
    1.90 +
    1.91 +  free (ref_runs);
    1.92 +  free (row_runs);
    1.93  }
    1.94  
    1.95  
    1.96 @@ -139,7 +163,7 @@
    1.97  
    1.98    struct pdf_obj *content_stream;
    1.99  
   1.100 -  image = pdf_calloc (sizeof (struct pdf_g4_image));
   1.101 +  image = pdf_calloc (1, sizeof (struct pdf_g4_image));
   1.102  
   1.103    image->width = width;
   1.104    image->height = height;
     2.1 diff -r 6e0551b59dba -r 7add7411c1c2 pdf.c
     2.2 --- a/pdf.c	Fri Feb 21 09:25:47 2003 +0000
     2.3 +++ b/pdf.c	Fri Feb 21 10:49:11 2003 +0000
     2.4 @@ -4,7 +4,7 @@
     2.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
     2.6   *
     2.7   * PDF routines
     2.8 - * $Id: pdf.c,v 1.3 2003/02/20 04:44:17 eric Exp $
     2.9 + * $Id: pdf.c,v 1.4 2003/02/21 02:49:11 eric Exp $
    2.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    2.11   *
    2.12   * This program is free software; you can redistribute it and/or modify
    2.13 @@ -53,7 +53,7 @@
    2.14  
    2.15  struct pdf_pages *pdf_new_pages (pdf_file_handle pdf_file)
    2.16  {
    2.17 -  struct pdf_pages *pages = pdf_calloc (sizeof (struct pdf_pages));
    2.18 +  struct pdf_pages *pages = pdf_calloc (1, sizeof (struct pdf_pages));
    2.19    pages->kids = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_ARRAY));
    2.20    pages->count = pdf_new_integer (0);
    2.21    pages->pages_dict = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
    2.22 @@ -68,7 +68,7 @@
    2.23  {
    2.24    pdf_file_handle pdf_file;
    2.25  
    2.26 -  pdf_file = pdf_calloc (sizeof (struct pdf_file));
    2.27 +  pdf_file = pdf_calloc (1, sizeof (struct pdf_file));
    2.28  
    2.29    pdf_file->f = fopen (filename, "wb");
    2.30    if (! pdf_file->f)
    2.31 @@ -154,7 +154,7 @@
    2.32  			      double width,
    2.33  			      double height)
    2.34  {
    2.35 -  pdf_page_handle page = pdf_calloc (sizeof (struct pdf_page));
    2.36 +  pdf_page_handle page = pdf_calloc (1, sizeof (struct pdf_page));
    2.37  
    2.38    page->pdf_file = pdf_file;
    2.39  
     3.1 diff -r 6e0551b59dba -r 7add7411c1c2 pdf_g4.c
     3.2 --- a/pdf_g4.c	Fri Feb 21 09:25:47 2003 +0000
     3.3 +++ b/pdf_g4.c	Fri Feb 21 10:49:11 2003 +0000
     3.4 @@ -4,7 +4,7 @@
     3.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
     3.6   *
     3.7   * PDF routines
     3.8 - * $Id: pdf_g4.c,v 1.5 2003/02/21 01:25:47 eric Exp $
     3.9 + * $Id: pdf_g4.c,v 1.6 2003/02/21 02:49:11 eric Exp $
    3.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    3.11   *
    3.12   * This program is free software; you can redistribute it and/or modify
    3.13 @@ -27,6 +27,7 @@
    3.14  #include <stdbool.h>
    3.15  #include <stdint.h>
    3.16  #include <stdio.h>
    3.17 +#include <stdlib.h>
    3.18  #include <string.h>
    3.19  
    3.20  
    3.21 @@ -37,6 +38,9 @@
    3.22  #include "pdf_private.h"
    3.23  
    3.24  
    3.25 +#define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0)
    3.26 +
    3.27 +
    3.28  struct pdf_g4_image
    3.29  {
    3.30    double width, height;
    3.31 @@ -94,28 +98,48 @@
    3.32  {
    3.33    struct pdf_g4_image *image = app_data;
    3.34  
    3.35 -#if 0
    3.36 -  pdf_stream_write_data (pdf_file, stream, image->data, image->len);
    3.37 -#else
    3.38 -  unsigned long row = 0;
    3.39 -  word_type *ref;
    3.40 -  word_type *raw;
    3.41 +  uint32_t row;
    3.42 +
    3.43 +  /* reference (previous) row */
    3.44 +  uint32_t *ref_runs = pdf_calloc (image->Columns, sizeof (uint32_t));
    3.45 +  uint32_t ref_run_count;
    3.46  
    3.47 -  ref = NULL;
    3.48 -  raw = image->bitmap->bits;
    3.49 +  /* row being converted */
    3.50 +  uint32_t *row_runs = pdf_calloc (image->Columns, sizeof (uint32_t));
    3.51 +  uint32_t row_run_count;
    3.52 +
    3.53 +  /* initialize reference row - all white */
    3.54 +  ref_runs [0] = image->Columns;
    3.55 +  ref_run_count = 0;
    3.56  
    3.57 -  while (row < image->Rows)
    3.58 +  for (row = image->bitmap->rect.min.y;
    3.59 +       row < image->bitmap->rect.max.y;
    3.60 +       row++)
    3.61      {
    3.62 -      pdf_stream_write_data (pdf_file, stream, (uint8_t *) raw,
    3.63 -			     image->bitmap->row_words * sizeof (word_type));
    3.64 +      row_run_count = get_row_run_lengths (image->bitmap,
    3.65 +					   row,
    3.66 +					   image->bitmap->rect.min.x,
    3.67 +					   image->bitmap->rect.max.x - 1,
    3.68 +					   image->Columns,  /* max_runs */
    3.69 +					   row_runs);
    3.70 +      pdf_assert (row_run_count > 0);
    3.71 +
    3.72 +      /* $$$ G4 encode the runs here */
    3.73  
    3.74 -      row++;
    3.75 -      ref = raw;
    3.76 -      raw += image->bitmap->row_words;
    3.77 +      /* pdf_stream_write_data (pdf_file, stream, image->data, image->len); */
    3.78 +
    3.79 +      SWAP (uint32_t *, row_runs, ref_runs);
    3.80 +      ref_run_count = row_run_count;
    3.81      }
    3.82 +
    3.83 +  
    3.84    /* $$$ generate and write EOFB code */
    3.85 -  /* $$$ flush any remaining buffered bits */
    3.86 -#endif
    3.87 +  pdf_stream_write_bits (pdf_file, stream, 24, 0x001001);
    3.88 +
    3.89 +  pdf_stream_flush_bits (pdf_file, stream);
    3.90 +
    3.91 +  free (ref_runs);
    3.92 +  free (row_runs);
    3.93  }
    3.94  
    3.95  
    3.96 @@ -139,7 +163,7 @@
    3.97  
    3.98    struct pdf_obj *content_stream;
    3.99  
   3.100 -  image = pdf_calloc (sizeof (struct pdf_g4_image));
   3.101 +  image = pdf_calloc (1, sizeof (struct pdf_g4_image));
   3.102  
   3.103    image->width = width;
   3.104    image->height = height;
     4.1 diff -r 6e0551b59dba -r 7add7411c1c2 pdf_prim.c
     4.2 --- a/pdf_prim.c	Fri Feb 21 09:25:47 2003 +0000
     4.3 +++ b/pdf_prim.c	Fri Feb 21 10:49:11 2003 +0000
     4.4 @@ -4,7 +4,7 @@
     4.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
     4.6   *
     4.7   * PDF routines
     4.8 - * $Id: pdf_prim.c,v 1.4 2003/02/21 01:25:47 eric Exp $
     4.9 + * $Id: pdf_prim.c,v 1.5 2003/02/21 02:49:11 eric Exp $
    4.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    4.11   *
    4.12   * This program is free software; you can redistribute it and/or modify
    4.13 @@ -66,6 +66,8 @@
    4.14  };
    4.15  
    4.16  
    4.17 +#define STREAM_BUF_SIZE 4096
    4.18 +
    4.19  struct pdf_stream
    4.20  {
    4.21    struct pdf_obj *stream_dict;
    4.22 @@ -74,6 +76,13 @@
    4.23    void *app_data;  /* arg to pass to callback */
    4.24    struct pdf_obj *filters;  /* name or array of names */
    4.25    struct pdf_obj *decode_parms;
    4.26 +
    4.27 +  /* The following fields are used by pdf_stream_write_bits() and
    4.28 +     pdf_stream_flush_bits(). */
    4.29 +  uint32_t byte_idx;  /* index to next byte position in data buffer */
    4.30 +  uint32_t bit_idx;   /* index to next bit position in data buffer,
    4.31 +			 0 = MSB, 7 = LSB */
    4.32 +  uint8_t data [STREAM_BUF_SIZE];
    4.33  };
    4.34  
    4.35  
    4.36 @@ -145,7 +154,7 @@
    4.37        }
    4.38  
    4.39    /* new entry */
    4.40 -  entry = pdf_calloc (sizeof (struct pdf_dict_entry));
    4.41 +  entry = pdf_calloc (1, sizeof (struct pdf_dict_entry));
    4.42  
    4.43    entry->next = dict_obj->val.dict.first;
    4.44    dict_obj->val.dict.first = entry;
    4.45 @@ -174,7 +183,7 @@
    4.46  
    4.47  void pdf_add_array_elem (struct pdf_obj *array_obj, struct pdf_obj *val)
    4.48  {
    4.49 -  struct pdf_array_elem *elem = pdf_calloc (sizeof (struct pdf_array_elem));
    4.50 +  struct pdf_array_elem *elem = pdf_calloc (1, sizeof (struct pdf_array_elem));
    4.51  
    4.52    if (array_obj->type == PT_IND_REF)
    4.53      array_obj = pdf_deref_ind_obj (array_obj);
    4.54 @@ -194,7 +203,7 @@
    4.55  
    4.56  struct pdf_obj *pdf_new_obj (pdf_obj_type type)
    4.57  {
    4.58 -  struct pdf_obj *obj = pdf_calloc (sizeof (struct pdf_obj));
    4.59 +  struct pdf_obj *obj = pdf_calloc (1, sizeof (struct pdf_obj));
    4.60    obj->type = type;
    4.61    return (obj);
    4.62  }
    4.63 @@ -453,6 +462,65 @@
    4.64  }
    4.65  
    4.66  
    4.67 +void pdf_stream_flush_bits (pdf_file_handle pdf_file,
    4.68 +			    struct pdf_obj *stream)
    4.69 +{
    4.70 +  struct pdf_stream *s = & stream->val.stream;
    4.71 +
    4.72 +  if (s->bit_idx)
    4.73 +    {
    4.74 +      /* zero remaining bits in last byte */
    4.75 +      s->data [s->byte_idx] &= ~ ((1 << (8 - s->bit_idx)) - 1);
    4.76 +      s->byte_idx++;
    4.77 +      s->bit_idx = 0;
    4.78 +    }
    4.79 +  pdf_stream_write_data (pdf_file, stream, 
    4.80 +			 (char *) & s->data [0],
    4.81 +			 s->byte_idx);
    4.82 +  s->byte_idx = 0;
    4.83 +}
    4.84 +
    4.85 +
    4.86 +static void pdf_stream_advance_byte (pdf_file_handle pdf_file,
    4.87 +				     struct pdf_obj *stream)
    4.88 +{
    4.89 +  struct pdf_stream *s = & stream->val.stream;
    4.90 +
    4.91 +  s->byte_idx++;
    4.92 +  s->bit_idx = 0;
    4.93 +  if (s->byte_idx == STREAM_BUF_SIZE)
    4.94 +    pdf_stream_flush_bits (pdf_file, stream);
    4.95 +}
    4.96 +
    4.97 +
    4.98 +void pdf_stream_write_bits (pdf_file_handle pdf_file,
    4.99 +			    struct pdf_obj *stream,
   4.100 +			    uint32_t count,
   4.101 +			    uint32_t bits)
   4.102 +{
   4.103 +  struct pdf_stream *s = & stream->val.stream;
   4.104 +
   4.105 +  uint32_t b2;  /* how many bits will fit in byte in data buffer */
   4.106 +  uint32_t c2;  /* how many bits to transfer on this iteration */
   4.107 +  uint32_t d2;  /* bits to transfer on this iteration */
   4.108 +
   4.109 +  while (count)
   4.110 +    {
   4.111 +      b2 = 8 - s->bit_idx;
   4.112 +      if (b2 >= count)
   4.113 +	c2 = count;
   4.114 +      else
   4.115 +	c2 = b2;
   4.116 +      d2 = bits >> (count - c2);
   4.117 +      s->data [s->byte_idx] |= (d2 << (b2 + c2));
   4.118 +      s->bit_idx += c2;
   4.119 +      if (s->bit_idx > 7)
   4.120 +	pdf_stream_advance_byte (pdf_file, stream);
   4.121 +      count -= c2;
   4.122 +    }
   4.123 +}
   4.124 +
   4.125 +
   4.126  void pdf_stream_printf (pdf_file_handle pdf_file,
   4.127  			struct pdf_obj *stream,
   4.128  			char *fmt, ...)
     5.1 diff -r 6e0551b59dba -r 7add7411c1c2 pdf_prim.h
     5.2 --- a/pdf_prim.h	Fri Feb 21 09:25:47 2003 +0000
     5.3 +++ b/pdf_prim.h	Fri Feb 21 10:49:11 2003 +0000
     5.4 @@ -4,7 +4,7 @@
     5.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
     5.6   *
     5.7   * PDF routines
     5.8 - * $Id: pdf_prim.h,v 1.3 2003/02/21 01:25:47 eric Exp $
     5.9 + * $Id: pdf_prim.h,v 1.4 2003/02/21 02:49:11 eric Exp $
    5.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    5.11   *
    5.12   * This program is free software; you can redistribute it and/or modify
    5.13 @@ -95,8 +95,19 @@
    5.14  				pdf_stream_write_callback callback,
    5.15  				void *app_data);
    5.16  
    5.17 -/* The callback should call pdf_stream_write_data or pdf_stream_printf
    5.18 -   to write the actual stream data. */
    5.19 +/* The callback should call pdf_stream_write_bits(), pdf_stream_write_data(),
    5.20 +   or pdf_stream_printf() to write the actual stream data.  If
    5.21 +   pdf_stream_write_bits() is used, pdf_stream_flush_bits() should be
    5.22 +   called after all the bits are written.  */
    5.23 +
    5.24 +void pdf_stream_write_bits (pdf_file_handle pdf_file,
    5.25 +			    struct pdf_obj *stream,
    5.26 +			    uint32_t count,
    5.27 +			    uint32_t bits);
    5.28 +
    5.29 +void pdf_stream_flush_bits (pdf_file_handle pdf_file,
    5.30 +			    struct pdf_obj *stream);
    5.31 +
    5.32  void pdf_stream_write_data (pdf_file_handle pdf_file,
    5.33  			    struct pdf_obj *stream,
    5.34  			    char *data,
     6.1 diff -r 6e0551b59dba -r 7add7411c1c2 pdf_util.c
     6.2 --- a/pdf_util.c	Fri Feb 21 09:25:47 2003 +0000
     6.3 +++ b/pdf_util.c	Fri Feb 21 10:49:11 2003 +0000
     6.4 @@ -4,7 +4,7 @@
     6.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
     6.6   *
     6.7   * PDF routines
     6.8 - * $Id: pdf_util.c,v 1.3 2003/02/20 04:44:17 eric Exp $
     6.9 + * $Id: pdf_util.c,v 1.4 2003/02/21 02:49:11 eric Exp $
    6.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    6.11   *
    6.12   * This program is free software; you can redistribute it and/or modify
    6.13 @@ -48,9 +48,9 @@
    6.14  }
    6.15  
    6.16  
    6.17 -void *pdf_calloc (long int size)
    6.18 +void *pdf_calloc (size_t nmemb, size_t size)
    6.19  {
    6.20 -  void *m = calloc (1, size);
    6.21 +  void *m = calloc (nmemb, size);
    6.22    if (! m)
    6.23      pdf_fatal ("failed to allocate memory\n");
    6.24    return (m);
    6.25 @@ -60,7 +60,7 @@
    6.26  char *pdf_strdup (char *s)
    6.27  {
    6.28    unsigned long len = strlen (s);
    6.29 -  char *s2 = pdf_calloc (len + 1);
    6.30 +  char *s2 = pdf_calloc (1, len + 1);
    6.31    strcpy (s2, s);
    6.32    return (s2);
    6.33  }
     7.1 diff -r 6e0551b59dba -r 7add7411c1c2 pdf_util.h
     7.2 --- a/pdf_util.h	Fri Feb 21 09:25:47 2003 +0000
     7.3 +++ b/pdf_util.h	Fri Feb 21 10:49:11 2003 +0000
     7.4 @@ -4,7 +4,7 @@
     7.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
     7.6   *
     7.7   * PDF routines
     7.8 - * $Id: pdf_util.h,v 1.2 2003/02/20 04:44:17 eric Exp $
     7.9 + * $Id: pdf_util.h,v 1.3 2003/02/21 02:49:11 eric Exp $
    7.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    7.11   *
    7.12   * This program is free software; you can redistribute it and/or modify
    7.13 @@ -26,7 +26,7 @@
    7.14  
    7.15  void pdf_fatal (char *fmt, ...);
    7.16  
    7.17 -void *pdf_calloc (long int size);
    7.18 +void *pdf_calloc (size_t nmemb, size_t size);
    7.19  
    7.20  char *pdf_strdup (char *s);
    7.21