Mon, 10 Mar 2003 09:49:50 +0000
Moved g4 encoding functions from pdf library to bitblt library.
Makefile | file | annotate | diff | revisions | |
bitblt.h | file | annotate | diff | revisions | |
bitblt_g4.c | file | annotate | diff | revisions | |
pdf_g4.c | file | annotate | diff | revisions | |
pdf_g4_table_gen.c | file | annotate | diff | revisions | |
pdf_prim.c | file | annotate | diff | revisions | |
pdf_prim.h | file | annotate | diff | revisions |
1.1 --- a/Makefile Sat Mar 08 10:02:13 2003 +0000 1.2 +++ b/Makefile Mon Mar 10 09:49:50 2003 +0000 1.3 @@ -1,6 +1,6 @@ 1.4 # t2p: build a PDF file out of one or more TIFF Class F Group 4 files 1.5 # Makefile 1.6 -# $Id: Makefile,v 1.20 2003/03/08 02:02:13 eric Exp $ 1.7 +# $Id: Makefile,v 1.21 2003/03/10 01:49:49 eric Exp $ 1.8 # Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com> 1.9 # 1.10 # This program is free software; you can redistribute it and/or modify 1.11 @@ -62,9 +62,8 @@ 1.12 TARGETS = t2p 1.13 1.14 CSRCS = t2p.c semantics.c \ 1.15 - bitblt.c bitblt_table_gen.c \ 1.16 - pdf_g4.c pdf_g4_table_gen.c \ 1.17 - pdf.c pdf_util.c pdf_prim.c pdf_bookmark.c pdf_name_tree.c 1.18 + bitblt.c bitblt_table_gen.c bitblt_g4.c g4_table_gen.c \ 1.19 + pdf.c pdf_util.c pdf_prim.c pdf_bookmark.c pdf_name_tree.c pdf_g4.c 1.20 OSRCS = scanner.l parser.y 1.21 HDRS = t2p.h semantics.h bitblt.h \ 1.22 pdf.h pdf_private.h pdf_util.h pdf_prim.h pdf_name_tree.h 1.23 @@ -75,7 +74,7 @@ 1.24 1.25 1.26 AUTO_CSRCS = scanner.c parser.tab.c 1.27 -AUTO_HDRS = parser.tab.h bitblt_tables.h pdf_g4_tables.h 1.28 +AUTO_HDRS = parser.tab.h bitblt_tables.h g4_tables.h 1.29 AUTO_MISC = parser.output 1.30 1.31 1.32 @@ -85,9 +84,9 @@ 1.33 all: $(TARGETS) $(TEST_TARGETS) 1.34 1.35 1.36 -t2p: t2p.o scanner.o semantics.o parser.tab.o bitblt.o \ 1.37 - pdf_g4.o \ 1.38 - pdf.o pdf_util.o pdf_prim.o pdf_bookmark.o pdf_name_tree.o 1.39 +t2p: t2p.o scanner.o semantics.o parser.tab.o bitblt.o bitblt_g4.o \ 1.40 + pdf.o pdf_util.o pdf_prim.o pdf_bookmark.o pdf_name_tree.o \ 1.41 + pdf_g4.o 1.42 $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@ 1.43 ifndef DEBUG 1.44 strip $@ 1.45 @@ -99,10 +98,10 @@ 1.46 1.47 bitblt_table_gen: bitblt_table_gen.o 1.48 1.49 -pdf_g4_tables.h: pdf_g4_table_gen 1.50 - ./pdf_g4_table_gen >pdf_g4_tables.h 1.51 +g4_tables.h: g4_table_gen 1.52 + ./g4_table_gen >g4_tables.h 1.53 1.54 -pdf_g4_table_gen: pdf_g4_table_gen.o 1.55 +g4_table_gen: g4_table_gen.o 1.56 1.57 1.58 dist: $(DISTFILES)
2.1 --- a/bitblt.h Sat Mar 08 10:02:13 2003 +0000 2.2 +++ b/bitblt.h Mon Mar 10 09:49:50 2003 +0000 2.3 @@ -4,7 +4,7 @@ 2.4 * will be compressed using ITU-T T.6 (G4) fax encoding. 2.5 * 2.6 * bitblt routines 2.7 - * $Id: bitblt.h,v 1.12 2003/02/23 09:40:41 eric Exp $ 2.8 + * $Id: bitblt.h,v 1.13 2003/03/10 01:49:50 eric Exp $ 2.9 * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com> 2.10 * 2.11 * This program is free software; you can redistribute it and/or modify 2.12 @@ -128,3 +128,6 @@ 2.13 int32_t min_x, int32_t max_x, 2.14 int32_t max_runs, 2.15 run_t *runs); 2.16 + 2.17 + 2.18 +void bitblt_write_g4 (Bitmap *bitmap, FILE *f);
3.1 --- a/bitblt_g4.c Sat Mar 08 10:02:13 2003 +0000 3.2 +++ b/bitblt_g4.c Mon Mar 10 09:49:50 2003 +0000 3.3 @@ -3,8 +3,8 @@ 3.4 * bilevel image files. The images in the resulting PDF file 3.5 * will be compressed using ITU-T T.6 (G4) fax encoding. 3.6 * 3.7 - * PDF routines 3.8 - * $Id: bitblt_g4.c,v 1.8 2003/03/05 12:44:33 eric Exp $ 3.9 + * G4 compression 3.10 + * $Id: bitblt_g4.c,v 1.9 2003/03/10 01:49:50 eric Exp $ 3.11 * Copyright 2003 Eric Smith <eric@brouhaha.com> 3.12 * 3.13 * This program is free software; you can redistribute it and/or modify 3.14 @@ -32,108 +32,111 @@ 3.15 3.16 3.17 #include "bitblt.h" 3.18 -#include "pdf.h" 3.19 -#include "pdf_util.h" 3.20 -#include "pdf_prim.h" 3.21 -#include "pdf_private.h" 3.22 3.23 3.24 -#include "pdf_g4_tables.h" 3.25 - 3.26 - 3.27 -#define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0) 3.28 +#include "g4_tables.h" 3.29 3.30 3.31 -struct pdf_g4_image 3.32 +#define BIT_BUF_SIZE 4096 3.33 + 3.34 +struct bit_buffer 3.35 { 3.36 - double width, height; 3.37 - double x, y; 3.38 - double r, g, b; /* fill color, only for ImageMask */ 3.39 - unsigned long Columns; 3.40 - unsigned long Rows; 3.41 - bool ImageMask; 3.42 - bool BlackIs1; 3.43 - Bitmap *bitmap; 3.44 - char XObject_name [4]; 3.45 + FILE *f; 3.46 + uint32_t byte_idx; /* index to next byte position in data buffer */ 3.47 + uint32_t bit_idx; /* index to next bit position in data buffer, 3.48 + 0 = MSB, 7 = LSB */ 3.49 + uint8_t data [BIT_BUF_SIZE]; 3.50 }; 3.51 3.52 3.53 -char pdf_new_XObject (pdf_page_handle pdf_page, struct pdf_obj *ind_ref) 3.54 +static void flush_bits (struct bit_buffer *buf) 3.55 { 3.56 - char XObject_name [4] = "Im "; 3.57 - 3.58 - XObject_name [2] = ++pdf_page->last_XObject_name; 3.59 - 3.60 - if (! pdf_page->XObject_dict) 3.61 + size_t s; 3.62 + if (buf->bit_idx) 3.63 { 3.64 - pdf_page->XObject_dict = pdf_new_obj (PT_DICTIONARY); 3.65 - pdf_set_dict_entry (pdf_page->resources, "XObject", pdf_page->XObject_dict); 3.66 + /* zero remaining bits in last byte */ 3.67 + buf->data [buf->byte_idx] &= ~ ((1 << (8 - buf->bit_idx)) - 1); 3.68 + buf->byte_idx++; 3.69 + buf->bit_idx = 0; 3.70 } 3.71 + s = fwrite (& buf->data [0], 1, buf->byte_idx, buf->f); 3.72 + /* $$$ should check result */ 3.73 + buf->byte_idx = 0; 3.74 +} 3.75 3.76 - pdf_set_dict_entry (pdf_page->XObject_dict, & XObject_name [0], ind_ref); 3.77 3.78 - return (pdf_page->last_XObject_name); 3.79 +static void advance_byte (struct bit_buffer *buf) 3.80 +{ 3.81 + buf->byte_idx++; 3.82 + buf->bit_idx = 0; 3.83 + if (buf->byte_idx == BIT_BUF_SIZE) 3.84 + flush_bits (buf); 3.85 } 3.86 3.87 3.88 -void pdf_write_g4_content_callback (pdf_file_handle pdf_file, 3.89 - struct pdf_obj *stream, 3.90 - void *app_data) 3.91 +static void write_bits (struct bit_buffer *buf, 3.92 + uint32_t count, 3.93 + uint32_t bits) 3.94 { 3.95 - struct pdf_g4_image *image = app_data; 3.96 + uint32_t b2; /* how many bits will fit in byte in data buffer */ 3.97 + uint32_t c2; /* how many bits to transfer on this iteration */ 3.98 + uint32_t d2; /* bits to transfer on this iteration */ 3.99 3.100 - /* transformation matrix is: width 0 0 height x y cm */ 3.101 - pdf_stream_printf (pdf_file, stream, "q %g 0 0 %g %g %g cm ", 3.102 - image->width, image->height, 3.103 - image->x, image->y); 3.104 - if (image->ImageMask) 3.105 - pdf_stream_printf (pdf_file, stream, "%g %g %g rg ", 3.106 - image->r, image->g, image->b); 3.107 - 3.108 - pdf_stream_printf (pdf_file, stream, "/%s Do Q\r\n", 3.109 - image->XObject_name); 3.110 + while (count) 3.111 + { 3.112 + b2 = 8 - buf->bit_idx; 3.113 + if (b2 >= count) 3.114 + c2 = count; 3.115 + else 3.116 + c2 = b2; 3.117 + d2 = bits >> (count - c2); 3.118 + buf->data [buf->byte_idx] |= (d2 << (b2 + c2)); 3.119 + buf->bit_idx += c2; 3.120 + if (buf->bit_idx > 7) 3.121 + advance_byte (buf); 3.122 + count -= c2; 3.123 + } 3.124 } 3.125 3.126 3.127 -static void pdf_g4_encode_horizontal_run (pdf_file_handle pdf_file, 3.128 - struct pdf_obj *stream, 3.129 - bool black, 3.130 - uint32_t run_length) 3.131 +static void g4_encode_horizontal_run (struct bit_buffer *buf, 3.132 + bool black, 3.133 + uint32_t run_length) 3.134 { 3.135 uint32_t i; 3.136 3.137 while (run_length >= 2560) 3.138 { 3.139 - pdf_stream_write_bits (pdf_file, stream, 12, 0x01f); 3.140 + write_bits (buf, 12, 0x01f); 3.141 run_length -= 2560; 3.142 } 3.143 3.144 if (run_length >= 1792) 3.145 { 3.146 i = (run_length - 1792) >> 6; 3.147 - pdf_stream_write_bits (pdf_file, stream, 3.148 - g4_long_makeup_code [i].count, 3.149 - g4_long_makeup_code [i].bits); 3.150 + write_bits (buf, 3.151 + g4_long_makeup_code [i].count, 3.152 + g4_long_makeup_code [i].bits); 3.153 run_length -= (1792 + (i << 6)); 3.154 } 3.155 else if (run_length >= 64) 3.156 { 3.157 i = (run_length >> 6) - 1; 3.158 - pdf_stream_write_bits (pdf_file, stream, 3.159 - g4_makeup_code [black] [i].count, 3.160 - g4_makeup_code [black] [i].bits); 3.161 + write_bits (buf, 3.162 + g4_makeup_code [black] [i].count, 3.163 + g4_makeup_code [black] [i].bits); 3.164 run_length -= (i + 1) << 6; 3.165 } 3.166 3.167 - pdf_stream_write_bits (pdf_file, stream, 3.168 - g4_h_code [black] [run_length].count, 3.169 - g4_h_code [black] [run_length].bits); 3.170 + write_bits (buf, 3.171 + g4_h_code [black] [run_length].count, 3.172 + g4_h_code [black] [run_length].bits); 3.173 } 3.174 3.175 3.176 -uint32_t find_transition (uint8_t *data, 3.177 - uint32_t pos, 3.178 - uint32_t width) 3.179 +static uint32_t find_transition (uint8_t *data, 3.180 + uint32_t pos, 3.181 + uint32_t width) 3.182 { 3.183 if (! data) 3.184 return (width); 3.185 @@ -141,11 +144,10 @@ 3.186 } 3.187 3.188 3.189 -static void pdf_g4_encode_row (pdf_file_handle pdf_file, 3.190 - struct pdf_obj *stream, 3.191 - uint32_t width, 3.192 - uint8_t *ref, 3.193 - uint8_t *row) 3.194 +static void g4_encode_row (struct bit_buffer *buf, 3.195 + uint32_t width, 3.196 + uint8_t *ref, 3.197 + uint8_t *row) 3.198 { 3.199 int a0, a1, a2; 3.200 int b1, b2; 3.201 @@ -167,152 +169,58 @@ 3.202 if (b2 < a1) 3.203 { 3.204 /* pass mode - 0001 */ 3.205 - pdf_stream_write_bits (pdf_file, stream, 4, 0x1); 3.206 + write_bits (buf, 4, 0x1); 3.207 a0 = b2; 3.208 } 3.209 else if (abs (a1 - b1) <= 3) 3.210 { 3.211 /* vertical mode */ 3.212 - pdf_stream_write_bits (pdf_file, stream, 3.213 - g4_vert_code [3 + a1 - b1].count, 3.214 - g4_vert_code [3 + a1 - b1].bits); 3.215 + write_bits (buf, 3.216 + g4_vert_code [3 + a1 - b1].count, 3.217 + g4_vert_code [3 + a1 - b1].bits); 3.218 a0 = a1; 3.219 } 3.220 else 3.221 { 3.222 /* horizontal mode - 001 */ 3.223 - pdf_stream_write_bits (pdf_file, stream, 3, 0x1); 3.224 - pdf_g4_encode_horizontal_run (pdf_file, stream, 3.225 - 0 /* $$$ color (a0) */, a1 - a0); 3.226 - pdf_g4_encode_horizontal_run (pdf_file, stream, 3.227 - 1 /* $$$ color (a1) */, a2 - a1); 3.228 + write_bits (buf, 3, 0x1); 3.229 + g4_encode_horizontal_run (buf, 0 /* $$$ color (a0) */, a1 - a0); 3.230 + g4_encode_horizontal_run (buf, 1 /* $$$ color (a1) */, a2 - a1); 3.231 a0 = a2; 3.232 } 3.233 } 3.234 } 3.235 3.236 3.237 -void pdf_write_g4_fax_image_callback (pdf_file_handle pdf_file, 3.238 - struct pdf_obj *stream, 3.239 - void *app_data) 3.240 +void bitblt_write_g4 (Bitmap *bitmap, FILE *f) 3.241 { 3.242 - struct pdf_g4_image *image = app_data; 3.243 - 3.244 uint32_t row; 3.245 + struct bit_buffer bb; 3.246 3.247 word_type *ref_line = NULL; /* reference (previous) row */ 3.248 - word_type *line = image->bitmap->bits; 3.249 + word_type *line = bitmap->bits; 3.250 + 3.251 + memset (& bb, 0, sizeof (bb)); 3.252 3.253 - for (row = image->bitmap->rect.min.y; 3.254 - row < image->bitmap->rect.max.y; 3.255 + bb.f = f; 3.256 + 3.257 + for (row = bitmap->rect.min.y; 3.258 + row < bitmap->rect.max.y; 3.259 row++) 3.260 { 3.261 - pdf_g4_encode_row (pdf_file, stream, image->Columns, 3.262 - (uint8_t *) ref_line, 3.263 - (uint8_t *) line); 3.264 + g4_encode_row (& bb, 3.265 + (bitmap->rect.max.x - bitmap->rect.min.x) + 1, 3.266 + (uint8_t *) ref_line, 3.267 + (uint8_t *) line); 3.268 ref_line = line; 3.269 - line += image->bitmap->row_words; 3.270 + line += bitmap->row_words; 3.271 } 3.272 3.273 3.274 /* write EOFB code */ 3.275 - pdf_stream_write_bits (pdf_file, stream, 24, 0x001001); 3.276 + write_bits (& bb, 24, 0x001001); 3.277 3.278 - pdf_stream_flush_bits (pdf_file, stream); 3.279 + flush_bits (& bb); 3.280 } 3.281 3.282 3.283 -void pdf_write_g4_fax_image (pdf_page_handle pdf_page, 3.284 - double x, 3.285 - double y, 3.286 - double width, 3.287 - double height, 3.288 - Bitmap *bitmap, 3.289 - bool ImageMask, 3.290 - double r, /* RGB fill color, only for ImageMask */ 3.291 - double g, 3.292 - double b, 3.293 - bool BlackIs1) /* boolean, typ. false */ 3.294 -{ 3.295 - struct pdf_g4_image *image; 3.296 - 3.297 - struct pdf_obj *stream; 3.298 - struct pdf_obj *stream_dict; 3.299 - struct pdf_obj *decode_parms; 3.300 - 3.301 - struct pdf_obj *content_stream; 3.302 - 3.303 - image = pdf_calloc (1, sizeof (struct pdf_g4_image)); 3.304 - 3.305 - image->width = width; 3.306 - image->height = height; 3.307 - image->x = x; 3.308 - image->y = y; 3.309 - image->r = r; 3.310 - image->g = g; 3.311 - image->b = b; 3.312 - 3.313 - image->bitmap = bitmap; 3.314 - image->Columns = bitmap->rect.max.x - bitmap->rect.min.x; 3.315 - image->Rows = bitmap->rect.max.y - bitmap->rect.min.y; 3.316 - image->ImageMask = ImageMask; 3.317 - image->BlackIs1 = BlackIs1; 3.318 - 3.319 - stream_dict = pdf_new_obj (PT_DICTIONARY); 3.320 - 3.321 - stream = pdf_new_ind_ref (pdf_page->pdf_file, 3.322 - pdf_new_stream (pdf_page->pdf_file, 3.323 - stream_dict, 3.324 - & pdf_write_g4_fax_image_callback, 3.325 - image)); 3.326 - 3.327 - strcpy (& image->XObject_name [0], "Im "); 3.328 - image->XObject_name [2] = pdf_new_XObject (pdf_page, stream); 3.329 - 3.330 - pdf_set_dict_entry (stream_dict, "Type", pdf_new_name ("XObject")); 3.331 - pdf_set_dict_entry (stream_dict, "Subtype", pdf_new_name ("Image")); 3.332 - pdf_set_dict_entry (stream_dict, "Name", pdf_new_name (& image->XObject_name [0])); 3.333 - pdf_set_dict_entry (stream_dict, "Width", pdf_new_integer (image->Columns)); 3.334 - pdf_set_dict_entry (stream_dict, "Height", pdf_new_integer (image->Rows)); 3.335 - pdf_set_dict_entry (stream_dict, "BitsPerComponent", pdf_new_integer (1)); 3.336 - if (ImageMask) 3.337 - pdf_set_dict_entry (stream_dict, "ImageMask", pdf_new_bool (ImageMask)); 3.338 - else 3.339 - pdf_set_dict_entry (stream_dict, "ColorSpace", pdf_new_name ("DeviceGray")); 3.340 - 3.341 - decode_parms = pdf_new_obj (PT_DICTIONARY); 3.342 - 3.343 - pdf_set_dict_entry (decode_parms, 3.344 - "K", 3.345 - pdf_new_integer (-1)); 3.346 - 3.347 - pdf_set_dict_entry (decode_parms, 3.348 - "Columns", 3.349 - pdf_new_integer (image->Columns)); 3.350 - 3.351 - pdf_set_dict_entry (decode_parms, 3.352 - "Rows", 3.353 - pdf_new_integer (image->Rows)); 3.354 - 3.355 - if (BlackIs1) 3.356 - pdf_set_dict_entry (decode_parms, 3.357 - "BlackIs1", 3.358 - pdf_new_bool (BlackIs1)); 3.359 - 3.360 - pdf_stream_add_filter (stream, "CCITTFaxDecode", decode_parms); 3.361 - 3.362 - /* the following will write the stream, using our callback function to 3.363 - get the actual data */ 3.364 - pdf_write_ind_obj (pdf_page->pdf_file, stream); 3.365 - 3.366 - content_stream = pdf_new_ind_ref (pdf_page->pdf_file, 3.367 - pdf_new_stream (pdf_page->pdf_file, 3.368 - pdf_new_obj (PT_DICTIONARY), 3.369 - & pdf_write_g4_content_callback, 3.370 - image)); 3.371 - 3.372 - pdf_set_dict_entry (pdf_page->page_dict, "Contents", content_stream); 3.373 - 3.374 - pdf_write_ind_obj (pdf_page->pdf_file, content_stream); 3.375 -} 3.376 -
4.1 --- a/pdf_g4.c Sat Mar 08 10:02:13 2003 +0000 4.2 +++ b/pdf_g4.c Mon Mar 10 09:49:50 2003 +0000 4.3 @@ -4,7 +4,7 @@ 4.4 * will be compressed using ITU-T T.6 (G4) fax encoding. 4.5 * 4.6 * PDF routines 4.7 - * $Id: pdf_g4.c,v 1.8 2003/03/05 12:44:33 eric Exp $ 4.8 + * $Id: pdf_g4.c,v 1.9 2003/03/10 01:49:50 eric Exp $ 4.9 * Copyright 2003 Eric Smith <eric@brouhaha.com> 4.10 * 4.11 * This program is free software; you can redistribute it and/or modify 4.12 @@ -38,9 +38,6 @@ 4.13 #include "pdf_private.h" 4.14 4.15 4.16 -#include "pdf_g4_tables.h" 4.17 - 4.18 - 4.19 #define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0) 4.20 4.21 4.22 @@ -95,130 +92,13 @@ 4.23 } 4.24 4.25 4.26 -static void pdf_g4_encode_horizontal_run (pdf_file_handle pdf_file, 4.27 - struct pdf_obj *stream, 4.28 - bool black, 4.29 - uint32_t run_length) 4.30 -{ 4.31 - uint32_t i; 4.32 - 4.33 - while (run_length >= 2560) 4.34 - { 4.35 - pdf_stream_write_bits (pdf_file, stream, 12, 0x01f); 4.36 - run_length -= 2560; 4.37 - } 4.38 - 4.39 - if (run_length >= 1792) 4.40 - { 4.41 - i = (run_length - 1792) >> 6; 4.42 - pdf_stream_write_bits (pdf_file, stream, 4.43 - g4_long_makeup_code [i].count, 4.44 - g4_long_makeup_code [i].bits); 4.45 - run_length -= (1792 + (i << 6)); 4.46 - } 4.47 - else if (run_length >= 64) 4.48 - { 4.49 - i = (run_length >> 6) - 1; 4.50 - pdf_stream_write_bits (pdf_file, stream, 4.51 - g4_makeup_code [black] [i].count, 4.52 - g4_makeup_code [black] [i].bits); 4.53 - run_length -= (i + 1) << 6; 4.54 - } 4.55 - 4.56 - pdf_stream_write_bits (pdf_file, stream, 4.57 - g4_h_code [black] [run_length].count, 4.58 - g4_h_code [black] [run_length].bits); 4.59 -} 4.60 - 4.61 - 4.62 -uint32_t find_transition (uint8_t *data, 4.63 - uint32_t pos, 4.64 - uint32_t width) 4.65 -{ 4.66 - if (! data) 4.67 - return (width); 4.68 - return (0); /* $$$ */ 4.69 -} 4.70 - 4.71 - 4.72 -static void pdf_g4_encode_row (pdf_file_handle pdf_file, 4.73 - struct pdf_obj *stream, 4.74 - uint32_t width, 4.75 - uint8_t *ref, 4.76 - uint8_t *row) 4.77 -{ 4.78 - int a0, a1, a2; 4.79 - int b1, b2; 4.80 - 4.81 - a0 = -1; 4.82 - 4.83 - while (a0 < width) 4.84 - { 4.85 - /* find a1, a2 */ 4.86 - a1 = find_transition (row, a0, width); 4.87 - a2 = find_transition (row, a1, width); 4.88 - 4.89 - /* find b1, b2 */ 4.90 - b1 = find_transition (ref, a0, width); 4.91 - if (0) /* $$$ b1 color = a0 color */ 4.92 - b1 = find_transition (ref, b1, width); 4.93 - b2 = find_transition (ref, b2, width); 4.94 - 4.95 - if (b2 < a1) 4.96 - { 4.97 - /* pass mode - 0001 */ 4.98 - pdf_stream_write_bits (pdf_file, stream, 4, 0x1); 4.99 - a0 = b2; 4.100 - } 4.101 - else if (abs (a1 - b1) <= 3) 4.102 - { 4.103 - /* vertical mode */ 4.104 - pdf_stream_write_bits (pdf_file, stream, 4.105 - g4_vert_code [3 + a1 - b1].count, 4.106 - g4_vert_code [3 + a1 - b1].bits); 4.107 - a0 = a1; 4.108 - } 4.109 - else 4.110 - { 4.111 - /* horizontal mode - 001 */ 4.112 - pdf_stream_write_bits (pdf_file, stream, 3, 0x1); 4.113 - pdf_g4_encode_horizontal_run (pdf_file, stream, 4.114 - 0 /* $$$ color (a0) */, a1 - a0); 4.115 - pdf_g4_encode_horizontal_run (pdf_file, stream, 4.116 - 1 /* $$$ color (a1) */, a2 - a1); 4.117 - a0 = a2; 4.118 - } 4.119 - } 4.120 -} 4.121 - 4.122 - 4.123 void pdf_write_g4_fax_image_callback (pdf_file_handle pdf_file, 4.124 struct pdf_obj *stream, 4.125 void *app_data) 4.126 { 4.127 struct pdf_g4_image *image = app_data; 4.128 4.129 - uint32_t row; 4.130 - 4.131 - word_type *ref_line = NULL; /* reference (previous) row */ 4.132 - word_type *line = image->bitmap->bits; 4.133 - 4.134 - for (row = image->bitmap->rect.min.y; 4.135 - row < image->bitmap->rect.max.y; 4.136 - row++) 4.137 - { 4.138 - pdf_g4_encode_row (pdf_file, stream, image->Columns, 4.139 - (uint8_t *) ref_line, 4.140 - (uint8_t *) line); 4.141 - ref_line = line; 4.142 - line += image->bitmap->row_words; 4.143 - } 4.144 - 4.145 - 4.146 - /* write EOFB code */ 4.147 - pdf_stream_write_bits (pdf_file, stream, 24, 0x001001); 4.148 - 4.149 - pdf_stream_flush_bits (pdf_file, stream); 4.150 + bitblt_write_g4 (image->bitmap, pdf_file->f); 4.151 } 4.152 4.153
5.1 --- a/pdf_g4_table_gen.c Sat Mar 08 10:02:13 2003 +0000 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,284 +0,0 @@ 5.4 -/* 5.5 - * t2p: Create a PDF file from the contents of one or more TIFF 5.6 - * bilevel image files. The images in the resulting PDF file 5.7 - * will be compressed using ITU-T T.6 (G4) fax encoding. 5.8 - * 5.9 - * G4 table generator 5.10 - * $Id: pdf_g4_table_gen.c,v 1.2 2003/03/05 12:44:33 eric Exp $ 5.11 - * Copyright 2003 Eric Smith <eric@brouhaha.com> 5.12 - * 5.13 - * This program is free software; you can redistribute it and/or modify 5.14 - * it under the terms of the GNU General Public License version 2 as 5.15 - * published by the Free Software Foundation. Note that permission is 5.16 - * not granted to redistribute this program under the terms of any 5.17 - * other version of the General Public License. 5.18 - * 5.19 - * This program is distributed in the hope that it will be useful, 5.20 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 5.21 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 5.22 - * GNU General Public License for more details. 5.23 - * 5.24 - * You should have received a copy of the GNU General Public License 5.25 - * along with this program; if not, write to the Free Software 5.26 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA 5.27 - */ 5.28 - 5.29 - 5.30 -#include <stdbool.h> 5.31 -#include <stdint.h> 5.32 -#include <stdio.h> 5.33 -#include <stdlib.h> 5.34 -#include <string.h> 5.35 - 5.36 - 5.37 -void emit_code (int indent, char *code, int last, bool comment, int cval) 5.38 -{ 5.39 - int i; 5.40 - int count = 0; 5.41 - uint32_t val = 0; 5.42 - 5.43 - printf ("%*s{ ", indent, ""); 5.44 - 5.45 - printf ("%d, ", strlen (code)); 5.46 - 5.47 - for (i = 0; i < strlen (code); i++) 5.48 - switch (code [i]) 5.49 - { 5.50 - case '0': val = (val << 1); count++; break; 5.51 - case '1': val = (val << 1) + 1; count++; break; 5.52 - case ' ': break; 5.53 - default: 5.54 - fprintf (stderr, "internal error\n"); 5.55 - exit (2); 5.56 - } 5.57 - 5.58 - printf ("0x%0*x", (count + 3)/4, val); 5.59 - 5.60 - printf (" }"); 5.61 - if (! last) 5.62 - printf (","); 5.63 - if (comment) 5.64 - printf (" /* %d */", cval); 5.65 - printf ("\n"); 5.66 -} 5.67 - 5.68 - 5.69 -char *long_makeup_code [12] = 5.70 - { 5.71 - /* 1792 */ "00000001000", 5.72 - /* 1856 */ "00000001100", 5.73 - /* 1920 */ "00000001101", 5.74 - /* 1984 */ "000000010010", 5.75 - /* 2048 */ "000000010011", 5.76 - /* 2112 */ "000000010100", 5.77 - /* 2176 */ "000000010101", 5.78 - /* 2240 */ "000000010110", 5.79 - /* 2304 */ "000000010111", 5.80 - /* 2368 */ "000000011100", 5.81 - /* 2432 */ "000000011101", 5.82 - /* 2496 */ "000000011110" 5.83 - /* 2560 "000000011111" hard-coded, doesn't need to be in table */ 5.84 - }; 5.85 - 5.86 - 5.87 -void print_long_makeup_code (void) 5.88 -{ 5.89 - int i; 5.90 - 5.91 - printf ("static g4_bits g4_long_makeup_code [12] =\n"); 5.92 - printf (" {\n"); 5.93 - for (i = 0; i < 12; i++) 5.94 - emit_code (4, long_makeup_code [i], i == 11, 1, i * 64 + 1792); 5.95 - printf (" };\n"); 5.96 -} 5.97 - 5.98 - 5.99 -char *makeup_code [64][2] = 5.100 - { 5.101 - { /* 64 */ "11011", "0000001111" }, 5.102 - { /* 128 */ "10010", "000011001000" }, 5.103 - { /* 192 */ "010111", "000011001001" }, 5.104 - { /* 256 */ "0110111", "000001011011" }, 5.105 - { /* 320 */ "00110110", "000000110011" }, 5.106 - { /* 384 */ "00110111", "000000110100" }, 5.107 - { /* 448 */ "01100100", "000000110101" }, 5.108 - { /* 512 */ "01100101", "0000001101100" }, 5.109 - { /* 576 */ "01101000", "0000001101101" }, 5.110 - { /* 640 */ "01100111", "0000001001010" }, 5.111 - { /* 704 */ "011001100", "0000001001011" }, 5.112 - { /* 768 */ "011001101", "0000001001100" }, 5.113 - { /* 832 */ "011010010", "0000001001101" }, 5.114 - { /* 896 */ "011010011", "0000001110010" }, 5.115 - { /* 960 */ "011010100", "0000001110011" }, 5.116 - { /* 1024 */ "011010101", "0000001110100" }, 5.117 - { /* 1088 */ "011010110", "0000001110101" }, 5.118 - { /* 1152 */ "011010111", "0000001110110" }, 5.119 - { /* 1216 */ "011011000", "0000001110111" }, 5.120 - { /* 1280 */ "011011001", "0000001010010" }, 5.121 - { /* 1344 */ "011011010", "0000001010011" }, 5.122 - { /* 1408 */ "011011011", "0000001010100" }, 5.123 - { /* 1472 */ "010011000", "0000001010101" }, 5.124 - { /* 1536 */ "010011001", "0000001011010" }, 5.125 - { /* 1600 */ "010011010", "0000001011011" }, 5.126 - { /* 1664 */ "011000", "0000001100100" }, 5.127 - { /* 1728 */ "010011011", "0000001100101" } 5.128 - }; 5.129 - 5.130 - 5.131 -void print_makeup_code (void) 5.132 -{ 5.133 - int i; 5.134 - 5.135 - printf ("static g4_bits g4_makeup_code [2] [27] =\n"); 5.136 - printf (" {\n"); 5.137 - printf (" {\n"); 5.138 - printf (" /* white */\n"); 5.139 - for (i = 0; i <= 26; i++) 5.140 - emit_code (6, makeup_code [i][0], i == 26, 1, (i + 1) * 64); 5.141 - printf (" },\n"); 5.142 - printf (" {\n"); 5.143 - printf (" /* black */\n"); 5.144 - for (i = 0; i <= 26; i++) 5.145 - emit_code (6, makeup_code [i][1], i == 26, 1, (i + 1) * 64); 5.146 - printf (" }\n"); 5.147 - printf (" };\n"); 5.148 -} 5.149 - 5.150 - 5.151 -char *h_code [64][2] = 5.152 - { 5.153 - { /* 0 */ "00110101", "0000110111" }, 5.154 - { /* 1 */ "000111", "010" }, 5.155 - { /* 2 */ "0111", "11" }, 5.156 - { /* 3 */ "1000", "10" }, 5.157 - { /* 4 */ "1011", "011" }, 5.158 - { /* 5 */ "1100", "0011" }, 5.159 - { /* 6 */ "1110", "0010" }, 5.160 - { /* 7 */ "1111", "00011" }, 5.161 - { /* 8 */ "10011", "000101" }, 5.162 - { /* 9 */ "10100", "000100" }, 5.163 - { /* 10 */ "00111", "0000100" }, 5.164 - { /* 11 */ "01000", "0000101" }, 5.165 - { /* 12 */ "001000", "0000111" }, 5.166 - { /* 13 */ "000011", "00000100" }, 5.167 - { /* 14 */ "110100", "00000111" }, 5.168 - { /* 15 */ "110101", "000011000" }, 5.169 - { /* 16 */ "101010", "0000010111" }, 5.170 - { /* 17 */ "101011", "0000011000" }, 5.171 - { /* 18 */ "0100111", "0000001000" }, 5.172 - { /* 19 */ "0001100", "00001100111" }, 5.173 - { /* 20 */ "0001000", "00001101000" }, 5.174 - { /* 21 */ "0010111", "00001101100" }, 5.175 - { /* 22 */ "0000011", "00000110111" }, 5.176 - { /* 23 */ "0000100", "00000101000" }, 5.177 - { /* 24 */ "0101000", "00000010111" }, 5.178 - { /* 25 */ "0101011", "00000011000" }, 5.179 - { /* 26 */ "0010011", "000011001010" }, 5.180 - { /* 27 */ "0100100", "000011001011" }, 5.181 - { /* 28 */ "0011000", "000011001100" }, 5.182 - { /* 29 */ "00000010", "000011001101" }, 5.183 - { /* 30 */ "00000011", "000001101000" }, 5.184 - { /* 31 */ "00011010", "000001101001" }, 5.185 - { /* 32 */ "00011011", "000001101010" }, 5.186 - { /* 33 */ "00010010", "000001101011" }, 5.187 - { /* 34 */ "00010011", "000011010010" }, 5.188 - { /* 35 */ "00010100", "000011010011" }, 5.189 - { /* 36 */ "00010101", "000011010100" }, 5.190 - { /* 37 */ "00010110", "000011010101" }, 5.191 - { /* 38 */ "00010111", "000011010110" }, 5.192 - { /* 39 */ "00101000", "000011010111" }, 5.193 - { /* 40 */ "00101001", "000001101100" }, 5.194 - { /* 41 */ "00101010", "000001101101" }, 5.195 - { /* 42 */ "00101011", "000011011010" }, 5.196 - { /* 43 */ "00101100", "000011011011" }, 5.197 - { /* 44 */ "00101101", "000001010100" }, 5.198 - { /* 45 */ "00000100", "000001010101" }, 5.199 - { /* 46 */ "00000101", "000001010110" }, 5.200 - { /* 47 */ "00001010", "000001010111" }, 5.201 - { /* 48 */ "00001011", "000001100100" }, 5.202 - { /* 49 */ "01010010", "000001100101" }, 5.203 - { /* 50 */ "01010011", "000001010010" }, 5.204 - { /* 51 */ "01010100", "000001010011" }, 5.205 - { /* 52 */ "01010101", "000000100100" }, 5.206 - { /* 53 */ "00100100", "000000110111" }, 5.207 - { /* 54 */ "00100101", "000000111000" }, 5.208 - { /* 55 */ "01011000", "000000100111" }, 5.209 - { /* 56 */ "01011001", "000000101000" }, 5.210 - { /* 57 */ "01011010", "000001011000" }, 5.211 - { /* 58 */ "01011011", "000001011001" }, 5.212 - { /* 59 */ "01001010", "000000101011" }, 5.213 - { /* 60 */ "01001011", "000000101100" }, 5.214 - { /* 61 */ "00110010", "000001011010" }, 5.215 - { /* 62 */ "00110011", "000001100110" }, 5.216 - { /* 63 */ "00110100", "000001100111" } 5.217 - }; 5.218 - 5.219 - 5.220 -void print_h_code (void) 5.221 -{ 5.222 - int i; 5.223 - 5.224 - printf ("static g4_bits g4_h_code [2] [64] =\n"); 5.225 - printf (" {\n"); 5.226 - printf (" {\n"); 5.227 - printf (" /* white */\n"); 5.228 - for (i = 0; i <= 63; i++) 5.229 - emit_code (6, h_code [i][0], i == 63, 1, i); 5.230 - printf (" },\n"); 5.231 - printf (" {\n"); 5.232 - printf (" /* black */\n"); 5.233 - for (i = 0; i <= 63; i++) 5.234 - emit_code (6, h_code [i][1], i == 63, 1, i); 5.235 - printf (" }\n"); 5.236 - printf (" };\n"); 5.237 -} 5.238 - 5.239 - 5.240 -char *v_code [7] = 5.241 - { 5.242 - /* -3 */ "0000010", 5.243 - /* -2 */ "000010", 5.244 - /* -1 */ "010", 5.245 - /* 0 */ "1", 5.246 - /* 1 */ "011", 5.247 - /* 2 */ "000011", 5.248 - /* 3 */ "0000011" 5.249 - }; 5.250 - 5.251 - 5.252 -void print_v_code (void) 5.253 -{ 5.254 - int i; 5.255 - 5.256 - printf ("static g4_bits g4_vert_code [7] =\n"); 5.257 - printf (" {\n"); 5.258 - for (i = 0; i <= 6; i++) 5.259 - emit_code (4, v_code [i], i == 6, 1, i - 3); 5.260 - printf (" };\n"); 5.261 -} 5.262 - 5.263 - 5.264 -int main (int argc, char *argv []) 5.265 -{ 5.266 - printf ("/* This file is automatically generated; do not edit */\n"); 5.267 - printf ("\n"); 5.268 - printf ("typedef struct\n"); 5.269 - printf ("{\n"); 5.270 - printf (" uint32_t count;\n"); 5.271 - printf (" uint32_t bits;\n"); 5.272 - printf ("} g4_bits;\n"); 5.273 - printf ("\n"); 5.274 - 5.275 - print_long_makeup_code (); 5.276 - printf ("\n"); 5.277 - 5.278 - print_makeup_code (); 5.279 - printf ("\n"); 5.280 - 5.281 - print_h_code (); 5.282 - printf ("\n"); 5.283 - 5.284 - print_v_code (); 5.285 - 5.286 - exit (0); 5.287 -}
6.1 --- a/pdf_prim.c Sat Mar 08 10:02:13 2003 +0000 6.2 +++ b/pdf_prim.c Mon Mar 10 09:49:50 2003 +0000 6.3 @@ -4,7 +4,7 @@ 6.4 * will be compressed using ITU-T T.6 (G4) fax encoding. 6.5 * 6.6 * PDF routines 6.7 - * $Id: pdf_prim.c,v 1.7 2003/03/07 03:02:31 eric Exp $ 6.8 + * $Id: pdf_prim.c,v 1.8 2003/03/10 01:49:50 eric Exp $ 6.9 * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com> 6.10 * 6.11 * This program is free software; you can redistribute it and/or modify 6.12 @@ -66,8 +66,6 @@ 6.13 }; 6.14 6.15 6.16 -#define STREAM_BUF_SIZE 4096 6.17 - 6.18 struct pdf_stream 6.19 { 6.20 struct pdf_obj *stream_dict; 6.21 @@ -76,13 +74,6 @@ 6.22 void *app_data; /* arg to pass to callback */ 6.23 struct pdf_obj *filters; /* name or array of names */ 6.24 struct pdf_obj *decode_parms; 6.25 - 6.26 - /* The following fields are used by pdf_stream_write_bits() and 6.27 - pdf_stream_flush_bits(). */ 6.28 - uint32_t byte_idx; /* index to next byte position in data buffer */ 6.29 - uint32_t bit_idx; /* index to next bit position in data buffer, 6.30 - 0 = MSB, 7 = LSB */ 6.31 - uint8_t data [STREAM_BUF_SIZE]; 6.32 }; 6.33 6.34 6.35 @@ -494,65 +485,6 @@ 6.36 } 6.37 6.38 6.39 -void pdf_stream_flush_bits (pdf_file_handle pdf_file, 6.40 - struct pdf_obj *stream) 6.41 -{ 6.42 - struct pdf_stream *s = & stream->val.stream; 6.43 - 6.44 - if (s->bit_idx) 6.45 - { 6.46 - /* zero remaining bits in last byte */ 6.47 - s->data [s->byte_idx] &= ~ ((1 << (8 - s->bit_idx)) - 1); 6.48 - s->byte_idx++; 6.49 - s->bit_idx = 0; 6.50 - } 6.51 - pdf_stream_write_data (pdf_file, stream, 6.52 - (char *) & s->data [0], 6.53 - s->byte_idx); 6.54 - s->byte_idx = 0; 6.55 -} 6.56 - 6.57 - 6.58 -static void pdf_stream_advance_byte (pdf_file_handle pdf_file, 6.59 - struct pdf_obj *stream) 6.60 -{ 6.61 - struct pdf_stream *s = & stream->val.stream; 6.62 - 6.63 - s->byte_idx++; 6.64 - s->bit_idx = 0; 6.65 - if (s->byte_idx == STREAM_BUF_SIZE) 6.66 - pdf_stream_flush_bits (pdf_file, stream); 6.67 -} 6.68 - 6.69 - 6.70 -void pdf_stream_write_bits (pdf_file_handle pdf_file, 6.71 - struct pdf_obj *stream, 6.72 - uint32_t count, 6.73 - uint32_t bits) 6.74 -{ 6.75 - struct pdf_stream *s = & stream->val.stream; 6.76 - 6.77 - uint32_t b2; /* how many bits will fit in byte in data buffer */ 6.78 - uint32_t c2; /* how many bits to transfer on this iteration */ 6.79 - uint32_t d2; /* bits to transfer on this iteration */ 6.80 - 6.81 - while (count) 6.82 - { 6.83 - b2 = 8 - s->bit_idx; 6.84 - if (b2 >= count) 6.85 - c2 = count; 6.86 - else 6.87 - c2 = b2; 6.88 - d2 = bits >> (count - c2); 6.89 - s->data [s->byte_idx] |= (d2 << (b2 + c2)); 6.90 - s->bit_idx += c2; 6.91 - if (s->bit_idx > 7) 6.92 - pdf_stream_advance_byte (pdf_file, stream); 6.93 - count -= c2; 6.94 - } 6.95 -} 6.96 - 6.97 - 6.98 void pdf_stream_printf (pdf_file_handle pdf_file, 6.99 struct pdf_obj *stream, 6.100 char *fmt, ...)
7.1 --- a/pdf_prim.h Sat Mar 08 10:02:13 2003 +0000 7.2 +++ b/pdf_prim.h Mon Mar 10 09:49:50 2003 +0000 7.3 @@ -4,7 +4,7 @@ 7.4 * will be compressed using ITU-T T.6 (G4) fax encoding. 7.5 * 7.6 * PDF routines 7.7 - * $Id: pdf_prim.h,v 1.6 2003/03/07 03:02:31 eric Exp $ 7.8 + * $Id: pdf_prim.h,v 1.7 2003/03/10 01:49:50 eric Exp $ 7.9 * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com> 7.10 * 7.11 * This program is free software; you can redistribute it and/or modify 7.12 @@ -99,15 +99,8 @@ 7.13 pdf_stream_write_callback callback, 7.14 void *app_data); 7.15 7.16 -/* The callback should call pdf_stream_write_bits(), pdf_stream_write_data(), 7.17 - or pdf_stream_printf() to write the actual stream data. If 7.18 - pdf_stream_write_bits() is used, pdf_stream_flush_bits() should be 7.19 - called after all the bits are written. */ 7.20 - 7.21 -void pdf_stream_write_bits (pdf_file_handle pdf_file, 7.22 - struct pdf_obj *stream, 7.23 - uint32_t count, 7.24 - uint32_t bits); 7.25 +/* The callback should call pdf_stream_write_data() or pdf_stream_printf() 7.26 + to write the actual stream data. */ 7.27 7.28 void pdf_stream_flush_bits (pdf_file_handle pdf_file, 7.29 struct pdf_obj *stream);