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, ...)