pdf_prim.c

changeset 67
7add7411c1c2
parent 66
6e0551b59dba
child 74
12bc5088172e
     1.1 diff -r 6e0551b59dba -r 7add7411c1c2 pdf_prim.c
     1.2 --- a/pdf_prim.c	Fri Feb 21 09:25:47 2003 +0000
     1.3 +++ b/pdf_prim.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: pdf_prim.c,v 1.4 2003/02/21 01:25:47 eric Exp $
     1.9 + * $Id: pdf_prim.c,v 1.5 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 @@ -66,6 +66,8 @@
    1.14  };
    1.15  
    1.16  
    1.17 +#define STREAM_BUF_SIZE 4096
    1.18 +
    1.19  struct pdf_stream
    1.20  {
    1.21    struct pdf_obj *stream_dict;
    1.22 @@ -74,6 +76,13 @@
    1.23    void *app_data;  /* arg to pass to callback */
    1.24    struct pdf_obj *filters;  /* name or array of names */
    1.25    struct pdf_obj *decode_parms;
    1.26 +
    1.27 +  /* The following fields are used by pdf_stream_write_bits() and
    1.28 +     pdf_stream_flush_bits(). */
    1.29 +  uint32_t byte_idx;  /* index to next byte position in data buffer */
    1.30 +  uint32_t bit_idx;   /* index to next bit position in data buffer,
    1.31 +			 0 = MSB, 7 = LSB */
    1.32 +  uint8_t data [STREAM_BUF_SIZE];
    1.33  };
    1.34  
    1.35  
    1.36 @@ -145,7 +154,7 @@
    1.37        }
    1.38  
    1.39    /* new entry */
    1.40 -  entry = pdf_calloc (sizeof (struct pdf_dict_entry));
    1.41 +  entry = pdf_calloc (1, sizeof (struct pdf_dict_entry));
    1.42  
    1.43    entry->next = dict_obj->val.dict.first;
    1.44    dict_obj->val.dict.first = entry;
    1.45 @@ -174,7 +183,7 @@
    1.46  
    1.47  void pdf_add_array_elem (struct pdf_obj *array_obj, struct pdf_obj *val)
    1.48  {
    1.49 -  struct pdf_array_elem *elem = pdf_calloc (sizeof (struct pdf_array_elem));
    1.50 +  struct pdf_array_elem *elem = pdf_calloc (1, sizeof (struct pdf_array_elem));
    1.51  
    1.52    if (array_obj->type == PT_IND_REF)
    1.53      array_obj = pdf_deref_ind_obj (array_obj);
    1.54 @@ -194,7 +203,7 @@
    1.55  
    1.56  struct pdf_obj *pdf_new_obj (pdf_obj_type type)
    1.57  {
    1.58 -  struct pdf_obj *obj = pdf_calloc (sizeof (struct pdf_obj));
    1.59 +  struct pdf_obj *obj = pdf_calloc (1, sizeof (struct pdf_obj));
    1.60    obj->type = type;
    1.61    return (obj);
    1.62  }
    1.63 @@ -453,6 +462,65 @@
    1.64  }
    1.65  
    1.66  
    1.67 +void pdf_stream_flush_bits (pdf_file_handle pdf_file,
    1.68 +			    struct pdf_obj *stream)
    1.69 +{
    1.70 +  struct pdf_stream *s = & stream->val.stream;
    1.71 +
    1.72 +  if (s->bit_idx)
    1.73 +    {
    1.74 +      /* zero remaining bits in last byte */
    1.75 +      s->data [s->byte_idx] &= ~ ((1 << (8 - s->bit_idx)) - 1);
    1.76 +      s->byte_idx++;
    1.77 +      s->bit_idx = 0;
    1.78 +    }
    1.79 +  pdf_stream_write_data (pdf_file, stream, 
    1.80 +			 (char *) & s->data [0],
    1.81 +			 s->byte_idx);
    1.82 +  s->byte_idx = 0;
    1.83 +}
    1.84 +
    1.85 +
    1.86 +static void pdf_stream_advance_byte (pdf_file_handle pdf_file,
    1.87 +				     struct pdf_obj *stream)
    1.88 +{
    1.89 +  struct pdf_stream *s = & stream->val.stream;
    1.90 +
    1.91 +  s->byte_idx++;
    1.92 +  s->bit_idx = 0;
    1.93 +  if (s->byte_idx == STREAM_BUF_SIZE)
    1.94 +    pdf_stream_flush_bits (pdf_file, stream);
    1.95 +}
    1.96 +
    1.97 +
    1.98 +void pdf_stream_write_bits (pdf_file_handle pdf_file,
    1.99 +			    struct pdf_obj *stream,
   1.100 +			    uint32_t count,
   1.101 +			    uint32_t bits)
   1.102 +{
   1.103 +  struct pdf_stream *s = & stream->val.stream;
   1.104 +
   1.105 +  uint32_t b2;  /* how many bits will fit in byte in data buffer */
   1.106 +  uint32_t c2;  /* how many bits to transfer on this iteration */
   1.107 +  uint32_t d2;  /* bits to transfer on this iteration */
   1.108 +
   1.109 +  while (count)
   1.110 +    {
   1.111 +      b2 = 8 - s->bit_idx;
   1.112 +      if (b2 >= count)
   1.113 +	c2 = count;
   1.114 +      else
   1.115 +	c2 = b2;
   1.116 +      d2 = bits >> (count - c2);
   1.117 +      s->data [s->byte_idx] |= (d2 << (b2 + c2));
   1.118 +      s->bit_idx += c2;
   1.119 +      if (s->bit_idx > 7)
   1.120 +	pdf_stream_advance_byte (pdf_file, stream);
   1.121 +      count -= c2;
   1.122 +    }
   1.123 +}
   1.124 +
   1.125 +
   1.126  void pdf_stream_printf (pdf_file_handle pdf_file,
   1.127  			struct pdf_obj *stream,
   1.128  			char *fmt, ...)