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