diff --git a/Makefile b/Makefile index 699895f..8f969d6 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # t2p: build a PDF file out of one or more TIFF Class F Group 4 files # Makefile -# $Id: Makefile,v 1.17 2003/03/04 17:58:36 eric Exp $ -# Copyright 2001 Eric Smith +# $Id: Makefile,v 1.18 2003/03/07 02:16:08 eric Exp $ +# Copyright 2001, 2002, 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 @@ -42,11 +42,13 @@ PACKAGE = t2p TARGETS = t2p bitblt_test -CSRCS = t2p.c semantics.c bitblt.c bitblt_test.c bitblt_table_gen.c \ - pdf.c pdf_util.c pdf_prim.c pdf_bookmark.c pdf_g4.c pdf_g4_table_gen.c +CSRCS = t2p.c semantics.c \ + bitblt.c bitblt_test.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 OSRCS = scanner.l parser.y HDRS = t2p.h semantics.h bitblt.h \ - pdf.h pdf_private.h pdf_util.h pdf_prim.h + pdf.h pdf_private.h pdf_util.h pdf_prim.h pdf_name_tree.h MISC = COPYING Makefile DISTFILES = $(MISC) $(HDRS) $(CSRCS) $(OSRCS) @@ -62,7 +64,8 @@ all: $(TARGETS) t2p: t2p.o scanner.o semantics.o parser.tab.o bitblt.o \ - pdf.o pdf_util.o pdf_prim.o pdf_bookmark.o pdf_g4.o + pdf_g4.o \ + pdf.o pdf_util.o pdf_prim.o pdf_bookmark.o pdf_name_tree.o bitblt_tables.h: bitblt_table_gen ./bitblt_table_gen >bitblt_tables.h diff --git a/TODO b/TODO index f17ef34..9ac63b7 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,5 @@ t2p TODO list -$Id: TODO,v 1.10 2003/03/04 17:58:36 eric Exp $ +$Id: TODO,v 1.11 2003/03/07 02:16:08 eric Exp $ No particular order. @@ -73,6 +73,7 @@ Adobe Systems Incorporated, Addison-Wesley, 1993.] * alternate destination specs (only is /Fit currently supported) * name trees, number trees + * when finalize is called, set flag and allow no further changes * page labels diff --git a/pdf_name_tree.c b/pdf_name_tree.c new file mode 100644 index 0000000..06f9f6a --- /dev/null +++ b/pdf_name_tree.c @@ -0,0 +1,203 @@ +/* + * 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. + * + * PDF routines + * $Id: pdf_name_tree.c,v 1.1 2003/03/07 02:16:08 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 + + +#include "bitblt.h" +#include "pdf.h" +#include "pdf_util.h" +#include "pdf_prim.h" +#include "pdf_private.h" +#include "pdf_name_tree.h" + + +#define MAX_NAME_TREE_NODE_ENTRIES 16 + + +struct pdf_name_tree_node +{ + struct pdf_obj *dict; /* indirect reference */ + + struct pdf_name_tree_node *parent; /* NULL for root */ + bool leaf; + + int count; /* how many kids or names/numbers are + attached to this node */ + + struct pdf_name_tree_node *kids [MAX_NAME_TREE_NODE_ENTRIES]; /* non-leaf only */ + + struct pdf_obj *min_key; + struct pdf_obj *max_key; + + /* following fields valid in leaf nodes only: */ + + struct pdf_obj *keys [MAX_NAME_TREE_NODE_ENTRIES]; + struct pdf_obj *values [MAX_NAME_TREE_NODE_ENTRIES]; +}; + + +struct pdf_name_tree *pdf_new_name_tree (pdf_file_handle pdf_file, + bool number_tree) +{ + struct pdf_name_tree *tree; + struct pdf_name_tree_node *root; + + root = pdf_calloc (1, sizeof (struct pdf_name_tree_node)); + tree = pdf_calloc (1, sizeof (struct pdf_name_tree)); + + tree->pdf_file = pdf_file; + tree->root = root; + tree->number_tree = number_tree; + + root->parent = NULL; + root->leaf = 1; + + return (tree); +} + + +static void pdf_split_name_tree_node (struct pdf_name_tree *tree, + struct pdf_name_tree_node *node) +{ + struct pdf_name_tree_node *new_node; + + if (node == tree->root) + { + /* create new root above current root */ + struct pdf_name_tree_node *new_root_node; + + new_root_node = pdf_calloc (1, sizeof (struct pdf_name_tree_node)); + + new_root_node->parent = NULL; + new_root_node->leaf = 0; + + new_root_node->count = 1; + new_root_node->kids [0] = node; + + new_root_node->min_key = node->min_key; + new_root_node->max_key = node->max_key; + + node->parent = new_root_node; + tree->root = new_root_node; + } + + new_node = pdf_calloc (1, sizeof (struct pdf_name_tree_node)); + new_node->parent = node->parent; + new_node->leaf = node->leaf; +} + + +static void pdf_add_tree_element (struct pdf_name_tree *tree, + struct pdf_obj *key, + struct pdf_obj *val) +{ + struct pdf_name_tree_node *node; + + /* find node which should contain element */ + node = tree->root; + + /* if node is full, split, recursing to root if necessary */ + if (node->count == MAX_NAME_TREE_NODE_ENTRIES) + { + pdf_split_name_tree_node (tree, node); + pdf_add_tree_element (tree, key, val); + return; + } +} + + +void pdf_add_name_tree_element (struct pdf_name_tree *tree, + char *key, + struct pdf_obj *val) +{ + struct pdf_obj *key_obj = pdf_new_string (key); + pdf_add_tree_element (tree, key_obj, val); +} + + +void pdf_add_number_tree_element (struct pdf_name_tree *tree, + long key, + struct pdf_obj *val) +{ + struct pdf_obj *key_obj = pdf_new_integer (key); + pdf_add_tree_element (tree, key_obj, val); +} + + +static void pdf_finalize_name_tree_node (struct pdf_name_tree *tree, + struct pdf_name_tree_node *node) +{ + int i; + + node->dict = pdf_new_ind_ref (tree->pdf_file, pdf_new_obj (PT_DICTIONARY)); + + if (node->leaf) + { + /* write Names or Nums array */ + struct pdf_obj *names = pdf_new_obj (PT_ARRAY); + for (i = 0; i < node->count; i++) + { + pdf_add_array_elem (names, node->keys [i]); + pdf_add_array_elem (names, node->values [i]); + } + pdf_set_dict_entry (node->dict, + tree->number_tree ? "Nums" : "Names", + names); + } + else + { + /* finalize the children first so that their dict ind ref is + available */ + for (i = 0; i < node->count; i++) + pdf_finalize_name_tree_node (tree, node->kids [i]); + + /* write Kids array */ + struct pdf_obj *kids = pdf_new_obj (PT_ARRAY); + for (i = 0; i < node->count; i++) + pdf_add_array_elem (kids, node->kids [i]->dict); + pdf_set_dict_entry (node->dict, "Kids", kids); + } + + if (! node->parent) + { + /* write Limits array */ + struct pdf_obj *limits = pdf_new_obj (PT_ARRAY); + pdf_add_array_elem (limits, node->min_key); + pdf_add_array_elem (limits, node->max_key); + pdf_set_dict_entry (node->dict, "Limits", limits); + } +} + + +void pdf_finalize_name_tree (struct pdf_name_tree *tree) +{ + pdf_finalize_name_tree_node (tree, tree->root); +} diff --git a/pdf_name_tree.h b/pdf_name_tree.h new file mode 100644 index 0000000..d05fc18 --- /dev/null +++ b/pdf_name_tree.h @@ -0,0 +1,50 @@ +/* + * 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. + * + * PDF routines + * $Id: pdf_name_tree.h,v 1.1 2003/03/07 02:16:08 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 + */ + + +struct pdf_name_tree +{ + pdf_file_handle pdf_file; + bool number_tree; /* false for name tree, + true for number tree */ + struct pdf_name_tree_node *root; +}; + + +struct pdf_name_tree *pdf_new_name_tree (pdf_file_handle pdf_file, + bool number_tree); + + +void pdf_add_name_tree_element (struct pdf_name_tree *tree, + char *key, + struct pdf_obj *val); + + +void pdf_add_number_tree_element (struct pdf_name_tree *tree, + long key, + struct pdf_obj *val); + + +void pdf_finalize_name_tree (struct pdf_name_tree *tree);