diff --git a/Makefile b/Makefile index c7a17c6..86c173e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # t2p: build a PDF file out of one or more TIFF Class F Group 4 files # Makefile -# $Id: Makefile,v 1.20 2003/03/08 02:02:13 eric Exp $ +# $Id: Makefile,v 1.21 2003/03/10 01:49:49 eric Exp $ # Copyright 2001, 2002, 2003 Eric Smith # # This program is free software; you can redistribute it and/or modify @@ -62,9 +62,8 @@ PACKAGE = t2p TARGETS = t2p CSRCS = t2p.c semantics.c \ - bitblt.c bitblt_table_gen.c \ - pdf_g4.c pdf_g4_table_gen.c \ - pdf.c pdf_util.c pdf_prim.c pdf_bookmark.c pdf_name_tree.c + bitblt.c bitblt_table_gen.c bitblt_g4.c g4_table_gen.c \ + pdf.c pdf_util.c pdf_prim.c pdf_bookmark.c pdf_name_tree.c pdf_g4.c OSRCS = scanner.l parser.y HDRS = t2p.h semantics.h bitblt.h \ pdf.h pdf_private.h pdf_util.h pdf_prim.h pdf_name_tree.h @@ -75,7 +74,7 @@ DISTNAME = $(PACKAGE)-$(VERSION) AUTO_CSRCS = scanner.c parser.tab.c -AUTO_HDRS = parser.tab.h bitblt_tables.h pdf_g4_tables.h +AUTO_HDRS = parser.tab.h bitblt_tables.h g4_tables.h AUTO_MISC = parser.output @@ -85,9 +84,9 @@ AUTO_MISC = parser.output all: $(TARGETS) $(TEST_TARGETS) -t2p: t2p.o scanner.o semantics.o parser.tab.o bitblt.o \ - pdf_g4.o \ - pdf.o pdf_util.o pdf_prim.o pdf_bookmark.o pdf_name_tree.o +t2p: t2p.o scanner.o semantics.o parser.tab.o bitblt.o bitblt_g4.o \ + pdf.o pdf_util.o pdf_prim.o pdf_bookmark.o pdf_name_tree.o \ + pdf_g4.o $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@ ifndef DEBUG strip $@ @@ -99,10 +98,10 @@ bitblt_tables.h: bitblt_table_gen bitblt_table_gen: bitblt_table_gen.o -pdf_g4_tables.h: pdf_g4_table_gen - ./pdf_g4_table_gen >pdf_g4_tables.h +g4_tables.h: g4_table_gen + ./g4_table_gen >g4_tables.h -pdf_g4_table_gen: pdf_g4_table_gen.o +g4_table_gen: g4_table_gen.o dist: $(DISTFILES) diff --git a/bitblt.h b/bitblt.h index 983e5fe..04ff6b8 100644 --- a/bitblt.h +++ b/bitblt.h @@ -4,7 +4,7 @@ * will be compressed using ITU-T T.6 (G4) fax encoding. * * bitblt routines - * $Id: bitblt.h,v 1.12 2003/02/23 09:40:41 eric Exp $ + * $Id: bitblt.h,v 1.13 2003/03/10 01:49:50 eric Exp $ * Copyright 2001, 2002, 2003 Eric Smith * * This program is free software; you can redistribute it and/or modify @@ -128,3 +128,6 @@ int32_t get_row_run_lengths (Bitmap *src, int32_t min_x, int32_t max_x, int32_t max_runs, run_t *runs); + + +void bitblt_write_g4 (Bitmap *bitmap, FILE *f); diff --git a/bitblt_g4.c b/bitblt_g4.c index cc386ac..a5a831e 100644 --- a/bitblt_g4.c +++ b/bitblt_g4.c @@ -3,8 +3,8 @@ * bilevel image files. The images in the resulting PDF file * will be compressed using ITU-T T.6 (G4) fax encoding. * - * PDF routines - * $Id: bitblt_g4.c,v 1.8 2003/03/05 12:44:33 eric Exp $ + * G4 compression + * $Id: bitblt_g4.c,v 1.9 2003/03/10 01:49:50 eric Exp $ * Copyright 2003 Eric Smith * * This program is free software; you can redistribute it and/or modify @@ -32,108 +32,111 @@ #include "bitblt.h" -#include "pdf.h" -#include "pdf_util.h" -#include "pdf_prim.h" -#include "pdf_private.h" -#include "pdf_g4_tables.h" +#include "g4_tables.h" -#define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0) +#define BIT_BUF_SIZE 4096 - -struct pdf_g4_image +struct bit_buffer { - double width, height; - double x, y; - double r, g, b; /* fill color, only for ImageMask */ - unsigned long Columns; - unsigned long Rows; - bool ImageMask; - bool BlackIs1; - Bitmap *bitmap; - char XObject_name [4]; + FILE *f; + uint32_t byte_idx; /* index to next byte position in data buffer */ + uint32_t bit_idx; /* index to next bit position in data buffer, + 0 = MSB, 7 = LSB */ + uint8_t data [BIT_BUF_SIZE]; }; -char pdf_new_XObject (pdf_page_handle pdf_page, struct pdf_obj *ind_ref) +static void flush_bits (struct bit_buffer *buf) { - char XObject_name [4] = "Im "; - - XObject_name [2] = ++pdf_page->last_XObject_name; - - if (! pdf_page->XObject_dict) + size_t s; + if (buf->bit_idx) { - pdf_page->XObject_dict = pdf_new_obj (PT_DICTIONARY); - pdf_set_dict_entry (pdf_page->resources, "XObject", pdf_page->XObject_dict); + /* zero remaining bits in last byte */ + buf->data [buf->byte_idx] &= ~ ((1 << (8 - buf->bit_idx)) - 1); + buf->byte_idx++; + buf->bit_idx = 0; } - - pdf_set_dict_entry (pdf_page->XObject_dict, & XObject_name [0], ind_ref); - - return (pdf_page->last_XObject_name); + s = fwrite (& buf->data [0], 1, buf->byte_idx, buf->f); + /* $$$ should check result */ + buf->byte_idx = 0; } -void pdf_write_g4_content_callback (pdf_file_handle pdf_file, - struct pdf_obj *stream, - void *app_data) +static void advance_byte (struct bit_buffer *buf) { - struct pdf_g4_image *image = app_data; - - /* transformation matrix is: width 0 0 height x y cm */ - pdf_stream_printf (pdf_file, stream, "q %g 0 0 %g %g %g cm ", - image->width, image->height, - image->x, image->y); - if (image->ImageMask) - pdf_stream_printf (pdf_file, stream, "%g %g %g rg ", - image->r, image->g, image->b); - - pdf_stream_printf (pdf_file, stream, "/%s Do Q\r\n", - image->XObject_name); + buf->byte_idx++; + buf->bit_idx = 0; + if (buf->byte_idx == BIT_BUF_SIZE) + flush_bits (buf); } -static void pdf_g4_encode_horizontal_run (pdf_file_handle pdf_file, - struct pdf_obj *stream, - bool black, - uint32_t run_length) +static void write_bits (struct bit_buffer *buf, + uint32_t count, + uint32_t bits) +{ + uint32_t b2; /* how many bits will fit in byte in data buffer */ + uint32_t c2; /* how many bits to transfer on this iteration */ + uint32_t d2; /* bits to transfer on this iteration */ + + while (count) + { + b2 = 8 - buf->bit_idx; + if (b2 >= count) + c2 = count; + else + c2 = b2; + d2 = bits >> (count - c2); + buf->data [buf->byte_idx] |= (d2 << (b2 + c2)); + buf->bit_idx += c2; + if (buf->bit_idx > 7) + advance_byte (buf); + count -= c2; + } +} + + +static void g4_encode_horizontal_run (struct bit_buffer *buf, + bool black, + uint32_t run_length) { uint32_t i; while (run_length >= 2560) { - pdf_stream_write_bits (pdf_file, stream, 12, 0x01f); + write_bits (buf, 12, 0x01f); run_length -= 2560; } if (run_length >= 1792) { i = (run_length - 1792) >> 6; - pdf_stream_write_bits (pdf_file, stream, - g4_long_makeup_code [i].count, - g4_long_makeup_code [i].bits); + write_bits (buf, + g4_long_makeup_code [i].count, + g4_long_makeup_code [i].bits); run_length -= (1792 + (i << 6)); } else if (run_length >= 64) { i = (run_length >> 6) - 1; - pdf_stream_write_bits (pdf_file, stream, - g4_makeup_code [black] [i].count, - g4_makeup_code [black] [i].bits); + write_bits (buf, + g4_makeup_code [black] [i].count, + g4_makeup_code [black] [i].bits); run_length -= (i + 1) << 6; } - pdf_stream_write_bits (pdf_file, stream, - g4_h_code [black] [run_length].count, - g4_h_code [black] [run_length].bits); + write_bits (buf, + g4_h_code [black] [run_length].count, + g4_h_code [black] [run_length].bits); } -uint32_t find_transition (uint8_t *data, - uint32_t pos, - uint32_t width) +static uint32_t find_transition (uint8_t *data, + uint32_t pos, + uint32_t width) { if (! data) return (width); @@ -141,11 +144,10 @@ uint32_t find_transition (uint8_t *data, } -static void pdf_g4_encode_row (pdf_file_handle pdf_file, - struct pdf_obj *stream, - uint32_t width, - uint8_t *ref, - uint8_t *row) +static void g4_encode_row (struct bit_buffer *buf, + uint32_t width, + uint8_t *ref, + uint8_t *row) { int a0, a1, a2; int b1, b2; @@ -167,152 +169,58 @@ static void pdf_g4_encode_row (pdf_file_handle pdf_file, if (b2 < a1) { /* pass mode - 0001 */ - pdf_stream_write_bits (pdf_file, stream, 4, 0x1); + write_bits (buf, 4, 0x1); a0 = b2; } else if (abs (a1 - b1) <= 3) { /* vertical mode */ - pdf_stream_write_bits (pdf_file, stream, - g4_vert_code [3 + a1 - b1].count, - g4_vert_code [3 + a1 - b1].bits); + write_bits (buf, + g4_vert_code [3 + a1 - b1].count, + g4_vert_code [3 + a1 - b1].bits); a0 = a1; } else { /* horizontal mode - 001 */ - pdf_stream_write_bits (pdf_file, stream, 3, 0x1); - pdf_g4_encode_horizontal_run (pdf_file, stream, - 0 /* $$$ color (a0) */, a1 - a0); - pdf_g4_encode_horizontal_run (pdf_file, stream, - 1 /* $$$ color (a1) */, a2 - a1); + write_bits (buf, 3, 0x1); + g4_encode_horizontal_run (buf, 0 /* $$$ color (a0) */, a1 - a0); + g4_encode_horizontal_run (buf, 1 /* $$$ color (a1) */, a2 - a1); a0 = a2; } } } -void pdf_write_g4_fax_image_callback (pdf_file_handle pdf_file, - struct pdf_obj *stream, - void *app_data) +void bitblt_write_g4 (Bitmap *bitmap, FILE *f) { - struct pdf_g4_image *image = app_data; - uint32_t row; + struct bit_buffer bb; word_type *ref_line = NULL; /* reference (previous) row */ - word_type *line = image->bitmap->bits; + word_type *line = bitmap->bits; - for (row = image->bitmap->rect.min.y; - row < image->bitmap->rect.max.y; + memset (& bb, 0, sizeof (bb)); + + bb.f = f; + + for (row = bitmap->rect.min.y; + row < bitmap->rect.max.y; row++) { - pdf_g4_encode_row (pdf_file, stream, image->Columns, - (uint8_t *) ref_line, - (uint8_t *) line); + g4_encode_row (& bb, + (bitmap->rect.max.x - bitmap->rect.min.x) + 1, + (uint8_t *) ref_line, + (uint8_t *) line); ref_line = line; - line += image->bitmap->row_words; + line += bitmap->row_words; } /* write EOFB code */ - pdf_stream_write_bits (pdf_file, stream, 24, 0x001001); + write_bits (& bb, 24, 0x001001); - pdf_stream_flush_bits (pdf_file, stream); + flush_bits (& bb); } -void pdf_write_g4_fax_image (pdf_page_handle pdf_page, - double x, - double y, - double width, - double height, - Bitmap *bitmap, - bool ImageMask, - double r, /* RGB fill color, only for ImageMask */ - double g, - double b, - bool BlackIs1) /* boolean, typ. false */ -{ - struct pdf_g4_image *image; - - struct pdf_obj *stream; - struct pdf_obj *stream_dict; - struct pdf_obj *decode_parms; - - struct pdf_obj *content_stream; - - image = pdf_calloc (1, sizeof (struct pdf_g4_image)); - - image->width = width; - image->height = height; - image->x = x; - image->y = y; - image->r = r; - image->g = g; - image->b = b; - - image->bitmap = bitmap; - image->Columns = bitmap->rect.max.x - bitmap->rect.min.x; - image->Rows = bitmap->rect.max.y - bitmap->rect.min.y; - image->ImageMask = ImageMask; - image->BlackIs1 = BlackIs1; - - stream_dict = pdf_new_obj (PT_DICTIONARY); - - stream = pdf_new_ind_ref (pdf_page->pdf_file, - pdf_new_stream (pdf_page->pdf_file, - stream_dict, - & pdf_write_g4_fax_image_callback, - image)); - - strcpy (& image->XObject_name [0], "Im "); - image->XObject_name [2] = pdf_new_XObject (pdf_page, stream); - - pdf_set_dict_entry (stream_dict, "Type", pdf_new_name ("XObject")); - pdf_set_dict_entry (stream_dict, "Subtype", pdf_new_name ("Image")); - pdf_set_dict_entry (stream_dict, "Name", pdf_new_name (& image->XObject_name [0])); - pdf_set_dict_entry (stream_dict, "Width", pdf_new_integer (image->Columns)); - pdf_set_dict_entry (stream_dict, "Height", pdf_new_integer (image->Rows)); - pdf_set_dict_entry (stream_dict, "BitsPerComponent", pdf_new_integer (1)); - if (ImageMask) - pdf_set_dict_entry (stream_dict, "ImageMask", pdf_new_bool (ImageMask)); - else - pdf_set_dict_entry (stream_dict, "ColorSpace", pdf_new_name ("DeviceGray")); - - decode_parms = pdf_new_obj (PT_DICTIONARY); - - pdf_set_dict_entry (decode_parms, - "K", - pdf_new_integer (-1)); - - pdf_set_dict_entry (decode_parms, - "Columns", - pdf_new_integer (image->Columns)); - - pdf_set_dict_entry (decode_parms, - "Rows", - pdf_new_integer (image->Rows)); - - if (BlackIs1) - pdf_set_dict_entry (decode_parms, - "BlackIs1", - pdf_new_bool (BlackIs1)); - - pdf_stream_add_filter (stream, "CCITTFaxDecode", decode_parms); - - /* the following will write the stream, using our callback function to - get the actual data */ - pdf_write_ind_obj (pdf_page->pdf_file, stream); - - content_stream = pdf_new_ind_ref (pdf_page->pdf_file, - pdf_new_stream (pdf_page->pdf_file, - pdf_new_obj (PT_DICTIONARY), - & pdf_write_g4_content_callback, - image)); - - pdf_set_dict_entry (pdf_page->page_dict, "Contents", content_stream); - - pdf_write_ind_obj (pdf_page->pdf_file, content_stream); -} - diff --git a/pdf_g4.c b/pdf_g4.c index 9f5b926..fdd051e 100644 --- a/pdf_g4.c +++ b/pdf_g4.c @@ -4,7 +4,7 @@ * will be compressed using ITU-T T.6 (G4) fax encoding. * * PDF routines - * $Id: pdf_g4.c,v 1.8 2003/03/05 12:44:33 eric Exp $ + * $Id: pdf_g4.c,v 1.9 2003/03/10 01:49:50 eric Exp $ * Copyright 2003 Eric Smith * * This program is free software; you can redistribute it and/or modify @@ -38,9 +38,6 @@ #include "pdf_private.h" -#include "pdf_g4_tables.h" - - #define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0) @@ -95,130 +92,13 @@ void pdf_write_g4_content_callback (pdf_file_handle pdf_file, } -static void pdf_g4_encode_horizontal_run (pdf_file_handle pdf_file, - struct pdf_obj *stream, - bool black, - uint32_t run_length) -{ - uint32_t i; - - while (run_length >= 2560) - { - pdf_stream_write_bits (pdf_file, stream, 12, 0x01f); - run_length -= 2560; - } - - if (run_length >= 1792) - { - i = (run_length - 1792) >> 6; - pdf_stream_write_bits (pdf_file, stream, - g4_long_makeup_code [i].count, - g4_long_makeup_code [i].bits); - run_length -= (1792 + (i << 6)); - } - else if (run_length >= 64) - { - i = (run_length >> 6) - 1; - pdf_stream_write_bits (pdf_file, stream, - g4_makeup_code [black] [i].count, - g4_makeup_code [black] [i].bits); - run_length -= (i + 1) << 6; - } - - pdf_stream_write_bits (pdf_file, stream, - g4_h_code [black] [run_length].count, - g4_h_code [black] [run_length].bits); -} - - -uint32_t find_transition (uint8_t *data, - uint32_t pos, - uint32_t width) -{ - if (! data) - return (width); - return (0); /* $$$ */ -} - - -static void pdf_g4_encode_row (pdf_file_handle pdf_file, - struct pdf_obj *stream, - uint32_t width, - uint8_t *ref, - uint8_t *row) -{ - int a0, a1, a2; - int b1, b2; - - a0 = -1; - - while (a0 < width) - { - /* find a1, a2 */ - a1 = find_transition (row, a0, width); - a2 = find_transition (row, a1, width); - - /* find b1, b2 */ - b1 = find_transition (ref, a0, width); - if (0) /* $$$ b1 color = a0 color */ - b1 = find_transition (ref, b1, width); - b2 = find_transition (ref, b2, width); - - if (b2 < a1) - { - /* pass mode - 0001 */ - pdf_stream_write_bits (pdf_file, stream, 4, 0x1); - a0 = b2; - } - else if (abs (a1 - b1) <= 3) - { - /* vertical mode */ - pdf_stream_write_bits (pdf_file, stream, - g4_vert_code [3 + a1 - b1].count, - g4_vert_code [3 + a1 - b1].bits); - a0 = a1; - } - else - { - /* horizontal mode - 001 */ - pdf_stream_write_bits (pdf_file, stream, 3, 0x1); - pdf_g4_encode_horizontal_run (pdf_file, stream, - 0 /* $$$ color (a0) */, a1 - a0); - pdf_g4_encode_horizontal_run (pdf_file, stream, - 1 /* $$$ color (a1) */, a2 - a1); - a0 = a2; - } - } -} - - void pdf_write_g4_fax_image_callback (pdf_file_handle pdf_file, struct pdf_obj *stream, void *app_data) { struct pdf_g4_image *image = app_data; - uint32_t row; - - word_type *ref_line = NULL; /* reference (previous) row */ - word_type *line = image->bitmap->bits; - - for (row = image->bitmap->rect.min.y; - row < image->bitmap->rect.max.y; - row++) - { - pdf_g4_encode_row (pdf_file, stream, image->Columns, - (uint8_t *) ref_line, - (uint8_t *) line); - ref_line = line; - line += image->bitmap->row_words; - } - - - /* write EOFB code */ - pdf_stream_write_bits (pdf_file, stream, 24, 0x001001); - - pdf_stream_flush_bits (pdf_file, stream); + bitblt_write_g4 (image->bitmap, pdf_file->f); } diff --git a/pdf_g4_table_gen.c b/pdf_g4_table_gen.c deleted file mode 100644 index faf6ade..0000000 --- a/pdf_g4_table_gen.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * t2p: Create a PDF file from the contents of one or more TIFF - * bilevel image files. The images in the resulting PDF file - * will be compressed using ITU-T T.6 (G4) fax encoding. - * - * G4 table generator - * $Id: pdf_g4_table_gen.c,v 1.2 2003/03/05 12:44:33 eric Exp $ - * Copyright 2003 Eric Smith - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. Note that permission is - * not granted to redistribute this program under the terms of any - * other version of the General Public License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA - */ - - -#include -#include -#include -#include -#include - - -void emit_code (int indent, char *code, int last, bool comment, int cval) -{ - int i; - int count = 0; - uint32_t val = 0; - - printf ("%*s{ ", indent, ""); - - printf ("%d, ", strlen (code)); - - for (i = 0; i < strlen (code); i++) - switch (code [i]) - { - case '0': val = (val << 1); count++; break; - case '1': val = (val << 1) + 1; count++; break; - case ' ': break; - default: - fprintf (stderr, "internal error\n"); - exit (2); - } - - printf ("0x%0*x", (count + 3)/4, val); - - printf (" }"); - if (! last) - printf (","); - if (comment) - printf (" /* %d */", cval); - printf ("\n"); -} - - -char *long_makeup_code [12] = - { - /* 1792 */ "00000001000", - /* 1856 */ "00000001100", - /* 1920 */ "00000001101", - /* 1984 */ "000000010010", - /* 2048 */ "000000010011", - /* 2112 */ "000000010100", - /* 2176 */ "000000010101", - /* 2240 */ "000000010110", - /* 2304 */ "000000010111", - /* 2368 */ "000000011100", - /* 2432 */ "000000011101", - /* 2496 */ "000000011110" - /* 2560 "000000011111" hard-coded, doesn't need to be in table */ - }; - - -void print_long_makeup_code (void) -{ - int i; - - printf ("static g4_bits g4_long_makeup_code [12] =\n"); - printf (" {\n"); - for (i = 0; i < 12; i++) - emit_code (4, long_makeup_code [i], i == 11, 1, i * 64 + 1792); - printf (" };\n"); -} - - -char *makeup_code [64][2] = - { - { /* 64 */ "11011", "0000001111" }, - { /* 128 */ "10010", "000011001000" }, - { /* 192 */ "010111", "000011001001" }, - { /* 256 */ "0110111", "000001011011" }, - { /* 320 */ "00110110", "000000110011" }, - { /* 384 */ "00110111", "000000110100" }, - { /* 448 */ "01100100", "000000110101" }, - { /* 512 */ "01100101", "0000001101100" }, - { /* 576 */ "01101000", "0000001101101" }, - { /* 640 */ "01100111", "0000001001010" }, - { /* 704 */ "011001100", "0000001001011" }, - { /* 768 */ "011001101", "0000001001100" }, - { /* 832 */ "011010010", "0000001001101" }, - { /* 896 */ "011010011", "0000001110010" }, - { /* 960 */ "011010100", "0000001110011" }, - { /* 1024 */ "011010101", "0000001110100" }, - { /* 1088 */ "011010110", "0000001110101" }, - { /* 1152 */ "011010111", "0000001110110" }, - { /* 1216 */ "011011000", "0000001110111" }, - { /* 1280 */ "011011001", "0000001010010" }, - { /* 1344 */ "011011010", "0000001010011" }, - { /* 1408 */ "011011011", "0000001010100" }, - { /* 1472 */ "010011000", "0000001010101" }, - { /* 1536 */ "010011001", "0000001011010" }, - { /* 1600 */ "010011010", "0000001011011" }, - { /* 1664 */ "011000", "0000001100100" }, - { /* 1728 */ "010011011", "0000001100101" } - }; - - -void print_makeup_code (void) -{ - int i; - - printf ("static g4_bits g4_makeup_code [2] [27] =\n"); - printf (" {\n"); - printf (" {\n"); - printf (" /* white */\n"); - for (i = 0; i <= 26; i++) - emit_code (6, makeup_code [i][0], i == 26, 1, (i + 1) * 64); - printf (" },\n"); - printf (" {\n"); - printf (" /* black */\n"); - for (i = 0; i <= 26; i++) - emit_code (6, makeup_code [i][1], i == 26, 1, (i + 1) * 64); - printf (" }\n"); - printf (" };\n"); -} - - -char *h_code [64][2] = - { - { /* 0 */ "00110101", "0000110111" }, - { /* 1 */ "000111", "010" }, - { /* 2 */ "0111", "11" }, - { /* 3 */ "1000", "10" }, - { /* 4 */ "1011", "011" }, - { /* 5 */ "1100", "0011" }, - { /* 6 */ "1110", "0010" }, - { /* 7 */ "1111", "00011" }, - { /* 8 */ "10011", "000101" }, - { /* 9 */ "10100", "000100" }, - { /* 10 */ "00111", "0000100" }, - { /* 11 */ "01000", "0000101" }, - { /* 12 */ "001000", "0000111" }, - { /* 13 */ "000011", "00000100" }, - { /* 14 */ "110100", "00000111" }, - { /* 15 */ "110101", "000011000" }, - { /* 16 */ "101010", "0000010111" }, - { /* 17 */ "101011", "0000011000" }, - { /* 18 */ "0100111", "0000001000" }, - { /* 19 */ "0001100", "00001100111" }, - { /* 20 */ "0001000", "00001101000" }, - { /* 21 */ "0010111", "00001101100" }, - { /* 22 */ "0000011", "00000110111" }, - { /* 23 */ "0000100", "00000101000" }, - { /* 24 */ "0101000", "00000010111" }, - { /* 25 */ "0101011", "00000011000" }, - { /* 26 */ "0010011", "000011001010" }, - { /* 27 */ "0100100", "000011001011" }, - { /* 28 */ "0011000", "000011001100" }, - { /* 29 */ "00000010", "000011001101" }, - { /* 30 */ "00000011", "000001101000" }, - { /* 31 */ "00011010", "000001101001" }, - { /* 32 */ "00011011", "000001101010" }, - { /* 33 */ "00010010", "000001101011" }, - { /* 34 */ "00010011", "000011010010" }, - { /* 35 */ "00010100", "000011010011" }, - { /* 36 */ "00010101", "000011010100" }, - { /* 37 */ "00010110", "000011010101" }, - { /* 38 */ "00010111", "000011010110" }, - { /* 39 */ "00101000", "000011010111" }, - { /* 40 */ "00101001", "000001101100" }, - { /* 41 */ "00101010", "000001101101" }, - { /* 42 */ "00101011", "000011011010" }, - { /* 43 */ "00101100", "000011011011" }, - { /* 44 */ "00101101", "000001010100" }, - { /* 45 */ "00000100", "000001010101" }, - { /* 46 */ "00000101", "000001010110" }, - { /* 47 */ "00001010", "000001010111" }, - { /* 48 */ "00001011", "000001100100" }, - { /* 49 */ "01010010", "000001100101" }, - { /* 50 */ "01010011", "000001010010" }, - { /* 51 */ "01010100", "000001010011" }, - { /* 52 */ "01010101", "000000100100" }, - { /* 53 */ "00100100", "000000110111" }, - { /* 54 */ "00100101", "000000111000" }, - { /* 55 */ "01011000", "000000100111" }, - { /* 56 */ "01011001", "000000101000" }, - { /* 57 */ "01011010", "000001011000" }, - { /* 58 */ "01011011", "000001011001" }, - { /* 59 */ "01001010", "000000101011" }, - { /* 60 */ "01001011", "000000101100" }, - { /* 61 */ "00110010", "000001011010" }, - { /* 62 */ "00110011", "000001100110" }, - { /* 63 */ "00110100", "000001100111" } - }; - - -void print_h_code (void) -{ - int i; - - printf ("static g4_bits g4_h_code [2] [64] =\n"); - printf (" {\n"); - printf (" {\n"); - printf (" /* white */\n"); - for (i = 0; i <= 63; i++) - emit_code (6, h_code [i][0], i == 63, 1, i); - printf (" },\n"); - printf (" {\n"); - printf (" /* black */\n"); - for (i = 0; i <= 63; i++) - emit_code (6, h_code [i][1], i == 63, 1, i); - printf (" }\n"); - printf (" };\n"); -} - - -char *v_code [7] = - { - /* -3 */ "0000010", - /* -2 */ "000010", - /* -1 */ "010", - /* 0 */ "1", - /* 1 */ "011", - /* 2 */ "000011", - /* 3 */ "0000011" - }; - - -void print_v_code (void) -{ - int i; - - printf ("static g4_bits g4_vert_code [7] =\n"); - printf (" {\n"); - for (i = 0; i <= 6; i++) - emit_code (4, v_code [i], i == 6, 1, i - 3); - printf (" };\n"); -} - - -int main (int argc, char *argv []) -{ - printf ("/* This file is automatically generated; do not edit */\n"); - printf ("\n"); - printf ("typedef struct\n"); - printf ("{\n"); - printf (" uint32_t count;\n"); - printf (" uint32_t bits;\n"); - printf ("} g4_bits;\n"); - printf ("\n"); - - print_long_makeup_code (); - printf ("\n"); - - print_makeup_code (); - printf ("\n"); - - print_h_code (); - printf ("\n"); - - print_v_code (); - - exit (0); -} diff --git a/pdf_prim.c b/pdf_prim.c index fee83c3..eb2ee26 100644 --- a/pdf_prim.c +++ b/pdf_prim.c @@ -4,7 +4,7 @@ * will be compressed using ITU-T T.6 (G4) fax encoding. * * PDF routines - * $Id: pdf_prim.c,v 1.7 2003/03/07 03:02:31 eric Exp $ + * $Id: pdf_prim.c,v 1.8 2003/03/10 01:49:50 eric Exp $ * Copyright 2001, 2002, 2003 Eric Smith * * This program is free software; you can redistribute it and/or modify @@ -66,8 +66,6 @@ struct pdf_dict }; -#define STREAM_BUF_SIZE 4096 - struct pdf_stream { struct pdf_obj *stream_dict; @@ -76,13 +74,6 @@ struct pdf_stream void *app_data; /* arg to pass to callback */ struct pdf_obj *filters; /* name or array of names */ struct pdf_obj *decode_parms; - - /* The following fields are used by pdf_stream_write_bits() and - pdf_stream_flush_bits(). */ - uint32_t byte_idx; /* index to next byte position in data buffer */ - uint32_t bit_idx; /* index to next bit position in data buffer, - 0 = MSB, 7 = LSB */ - uint8_t data [STREAM_BUF_SIZE]; }; @@ -494,65 +485,6 @@ void pdf_stream_write_data (pdf_file_handle pdf_file, } -void pdf_stream_flush_bits (pdf_file_handle pdf_file, - struct pdf_obj *stream) -{ - struct pdf_stream *s = & stream->val.stream; - - if (s->bit_idx) - { - /* zero remaining bits in last byte */ - s->data [s->byte_idx] &= ~ ((1 << (8 - s->bit_idx)) - 1); - s->byte_idx++; - s->bit_idx = 0; - } - pdf_stream_write_data (pdf_file, stream, - (char *) & s->data [0], - s->byte_idx); - s->byte_idx = 0; -} - - -static void pdf_stream_advance_byte (pdf_file_handle pdf_file, - struct pdf_obj *stream) -{ - struct pdf_stream *s = & stream->val.stream; - - s->byte_idx++; - s->bit_idx = 0; - if (s->byte_idx == STREAM_BUF_SIZE) - pdf_stream_flush_bits (pdf_file, stream); -} - - -void pdf_stream_write_bits (pdf_file_handle pdf_file, - struct pdf_obj *stream, - uint32_t count, - uint32_t bits) -{ - struct pdf_stream *s = & stream->val.stream; - - uint32_t b2; /* how many bits will fit in byte in data buffer */ - uint32_t c2; /* how many bits to transfer on this iteration */ - uint32_t d2; /* bits to transfer on this iteration */ - - while (count) - { - b2 = 8 - s->bit_idx; - if (b2 >= count) - c2 = count; - else - c2 = b2; - d2 = bits >> (count - c2); - s->data [s->byte_idx] |= (d2 << (b2 + c2)); - s->bit_idx += c2; - if (s->bit_idx > 7) - pdf_stream_advance_byte (pdf_file, stream); - count -= c2; - } -} - - void pdf_stream_printf (pdf_file_handle pdf_file, struct pdf_obj *stream, char *fmt, ...) diff --git a/pdf_prim.h b/pdf_prim.h index a6a410c..b77241e 100644 --- a/pdf_prim.h +++ b/pdf_prim.h @@ -4,7 +4,7 @@ * will be compressed using ITU-T T.6 (G4) fax encoding. * * PDF routines - * $Id: pdf_prim.h,v 1.6 2003/03/07 03:02:31 eric Exp $ + * $Id: pdf_prim.h,v 1.7 2003/03/10 01:49:50 eric Exp $ * Copyright 2001, 2002, 2003 Eric Smith * * This program is free software; you can redistribute it and/or modify @@ -99,15 +99,8 @@ struct pdf_obj *pdf_new_stream (pdf_file_handle pdf_file, pdf_stream_write_callback callback, void *app_data); -/* The callback should call pdf_stream_write_bits(), pdf_stream_write_data(), - or pdf_stream_printf() to write the actual stream data. If - pdf_stream_write_bits() is used, pdf_stream_flush_bits() should be - called after all the bits are written. */ - -void pdf_stream_write_bits (pdf_file_handle pdf_file, - struct pdf_obj *stream, - uint32_t count, - uint32_t bits); +/* The callback should call pdf_stream_write_data() or pdf_stream_printf() + to write the actual stream data. */ void pdf_stream_flush_bits (pdf_file_handle pdf_file, struct pdf_obj *stream);