added bookmark support.

Wed, 05 Mar 2003 01:58:36 +0000

author
eric
date
Wed, 05 Mar 2003 01:58:36 +0000
changeset 74
12bc5088172e
parent 73
6e306105c128
child 75
29d7cbc7c251

added bookmark support.

Makefile file | annotate | diff | revisions
TODO file | annotate | diff | revisions
pdf.h file | annotate | diff | revisions
pdf_bookmark.c file | annotate | diff | revisions
pdf_prim.c file | annotate | diff | revisions
pdf_prim.h file | annotate | diff | revisions
pdf_private.h file | annotate | diff | revisions
pdf_util.h file | annotate | diff | revisions
t2p.c file | annotate | diff | revisions
tumble.c file | annotate | diff | revisions
     1.1 diff -r 6e306105c128 -r 12bc5088172e Makefile
     1.2 --- a/Makefile	Wed Mar 05 01:58:31 2003 +0000
     1.3 +++ b/Makefile	Wed Mar 05 01:58:36 2003 +0000
     1.4 @@ -1,6 +1,6 @@
     1.5  # t2p: build a PDF file out of one or more TIFF Class F Group 4 files
     1.6  # Makefile
     1.7 -# $Id: Makefile,v 1.16 2003/02/22 02:02:06 eric Exp $
     1.8 +# $Id: Makefile,v 1.17 2003/03/04 17:58:36 eric Exp $
     1.9  # Copyright 2001 Eric Smith <eric@brouhaha.com>
    1.10  #
    1.11  # This program is free software; you can redistribute it and/or modify
    1.12 @@ -43,7 +43,7 @@
    1.13  TARGETS = t2p bitblt_test
    1.14  
    1.15  CSRCS = t2p.c semantics.c bitblt.c bitblt_test.c bitblt_table_gen.c \
    1.16 -	pdf.c pdf_util.c pdf_prim.c pdf_g4.c pdf_g4_table_gen.c
    1.17 +	pdf.c pdf_util.c pdf_prim.c pdf_bookmark.c pdf_g4.c pdf_g4_table_gen.c
    1.18  OSRCS = scanner.l parser.y
    1.19  HDRS = t2p.h semantics.h bitblt.h \
    1.20  	pdf.h pdf_private.h pdf_util.h pdf_prim.h
    1.21 @@ -62,7 +62,7 @@
    1.22  
    1.23  
    1.24  t2p: t2p.o scanner.o semantics.o parser.tab.o bitblt.o \
    1.25 -	pdf.o pdf_util.o pdf_prim.o pdf_g4.o
    1.26 +	pdf.o pdf_util.o pdf_prim.o pdf_bookmark.o pdf_g4.o
    1.27  
    1.28  bitblt_tables.h: bitblt_table_gen
    1.29  	./bitblt_table_gen >bitblt_tables.h
     2.1 diff -r 6e306105c128 -r 12bc5088172e TODO
     2.2 --- a/TODO	Wed Mar 05 01:58:31 2003 +0000
     2.3 +++ b/TODO	Wed Mar 05 01:58:36 2003 +0000
     2.4 @@ -1,5 +1,5 @@
     2.5  t2p TODO list
     2.6 -$Id: TODO,v 1.9 2003/02/21 01:25:47 eric Exp $
     2.7 +$Id: TODO,v 1.10 2003/03/04 17:58:36 eric Exp $
     2.8  
     2.9  No particular order.
    2.10  
    2.11 @@ -70,6 +70,7 @@
    2.12  * proper output of real numbers - variable precision, no exponent
    2.13  
    2.14  * bookmarks (outline)
    2.15 +    * alternate destination specs (only is /Fit currently supported)
    2.16  
    2.17  * name trees, number trees
    2.18  
     3.1 diff -r 6e306105c128 -r 12bc5088172e pdf.h
     3.2 --- a/pdf.h	Wed Mar 05 01:58:31 2003 +0000
     3.3 +++ b/pdf.h	Wed Mar 05 01:58:36 2003 +0000
     3.4 @@ -4,7 +4,7 @@
     3.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
     3.6   *
     3.7   * PDF routines
     3.8 - * $Id: pdf.h,v 1.4 2003/02/21 01:25:47 eric Exp $
     3.9 + * $Id: pdf.h,v 1.5 2003/03/04 17:58:36 eric Exp $
    3.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    3.11   *
    3.12   * This program is free software; you can redistribute it and/or modify
    3.13 @@ -28,6 +28,8 @@
    3.14  
    3.15  typedef struct pdf_page *pdf_page_handle;
    3.16  
    3.17 +typedef struct pdf_bookmark *pdf_bookmark_handle;
    3.18 +
    3.19  
    3.20  void pdf_init (void);
    3.21  
    3.22 @@ -68,6 +70,11 @@
    3.23  
    3.24  void pdf_set_page_number (pdf_page_handle pdf_page, char *page_number);
    3.25  
    3.26 -void pdf_bookmark (pdf_page_handle pdf_page, int level, char *name);
    3.27 +/* Create a new bookmark, under the specified parent, or at the top
    3.28 +   level if parent is NULL. */
    3.29 +pdf_bookmark_handle pdf_new_bookmark (pdf_bookmark_handle parent,
    3.30 +				      char *title,
    3.31 +				      bool open,
    3.32 +				      pdf_page_handle pdf_page);
    3.33  
    3.34  void pdf_insert_tiff_image (pdf_page_handle pdf_page, char *filename);
     4.1 diff -r 6e306105c128 -r 12bc5088172e pdf_bookmark.c
     4.2 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 +++ b/pdf_bookmark.c	Wed Mar 05 01:58:36 2003 +0000
     4.4 @@ -0,0 +1,132 @@
     4.5 +/*
     4.6 + * t2p: Create a PDF file from the contents of one or more TIFF
     4.7 + *      bilevel image files.  The images in the resulting PDF file
     4.8 + *      will be compressed using ITU-T T.6 (G4) fax encoding.
     4.9 + *
    4.10 + * PDF routines
    4.11 + * $Id: pdf_bookmark.c,v 1.1 2003/03/04 17:58:36 eric Exp $
    4.12 + * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    4.13 + *
    4.14 + * This program is free software; you can redistribute it and/or modify
    4.15 + * it under the terms of the GNU General Public License version 2 as
    4.16 + * published by the Free Software Foundation.  Note that permission is
    4.17 + * not granted to redistribute this program under the terms of any
    4.18 + * other version of the General Public License.
    4.19 + *
    4.20 + * This program is distributed in the hope that it will be useful,
    4.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.23 + * GNU General Public License for more details.
    4.24 + *
    4.25 + * You should have received a copy of the GNU General Public License
    4.26 + * along with this program; if not, write to the Free Software
    4.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
    4.28 + */
    4.29 +
    4.30 +
    4.31 +#include <stdbool.h>
    4.32 +#include <stdint.h>
    4.33 +#include <stdio.h>
    4.34 +#include <stdlib.h>
    4.35 +#include <string.h>
    4.36 +
    4.37 +
    4.38 +#include "bitblt.h"
    4.39 +#include "pdf.h"
    4.40 +#include "pdf_util.h"
    4.41 +#include "pdf_prim.h"
    4.42 +#include "pdf_private.h"
    4.43 +
    4.44 +
    4.45 +static void pdf_bookmark_update_count (pdf_bookmark_handle entry)
    4.46 +{
    4.47 +  struct pdf_obj *count_obj;
    4.48 +
    4.49 +  while (entry)
    4.50 +    {
    4.51 +      count_obj = pdf_get_dict_entry (entry->dict, "Count");
    4.52 +      if (! count_obj)
    4.53 +	{
    4.54 +	  count_obj = pdf_new_integer (0);
    4.55 +	  pdf_set_dict_entry (entry->dict, "Count", count_obj);
    4.56 +	}
    4.57 +      pdf_set_integer (count_obj,
    4.58 +		       pdf_get_integer (count_obj) +
    4.59 +		       ((entry->open) ? 1 : -1));
    4.60 +      entry = entry->parent;
    4.61 +    }
    4.62 +}
    4.63 +
    4.64 +
    4.65 +/* Create a new bookmark, under the specified parent, or at the top
    4.66 +   level if parent is NULL. */
    4.67 +pdf_bookmark_handle pdf_new_bookmark (pdf_bookmark_handle parent,
    4.68 +				      char *title,
    4.69 +				      bool open,
    4.70 +				      pdf_page_handle pdf_page)
    4.71 +{
    4.72 +  pdf_file_handle pdf_file = pdf_page->pdf_file;
    4.73 +  struct pdf_bookmark *root;
    4.74 +  struct pdf_bookmark *entry;
    4.75 +
    4.76 +  struct pdf_obj *dest_array;
    4.77 +
    4.78 +  root = pdf_file->outline_root;
    4.79 +  if (! root)
    4.80 +    {
    4.81 +      root = pdf_calloc (1, sizeof (struct pdf_bookmark));
    4.82 +      root->dict = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
    4.83 +      pdf_set_dict_entry (root->dict, "Count", pdf_new_integer (0));
    4.84 +
    4.85 +      pdf_file->outline_root = root;
    4.86 +      pdf_set_dict_entry (pdf_file->catalog, "Outlines", root->dict);
    4.87 +    }
    4.88 +
    4.89 +  entry = pdf_calloc (1, sizeof (struct pdf_bookmark));
    4.90 +  entry->dict = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
    4.91 +  entry->open = open;
    4.92 +
    4.93 +  pdf_set_dict_entry (entry->dict, "Title", pdf_new_string (title));
    4.94 +
    4.95 +  dest_array = pdf_new_obj (PT_ARRAY);
    4.96 +  pdf_add_array_elem (dest_array, pdf_page->page_dict);
    4.97 +  pdf_add_array_elem (dest_array, pdf_new_name ("Fit"));
    4.98 +  pdf_set_dict_entry (entry->dict, "Dest", dest_array);
    4.99 +
   4.100 +  if (parent)
   4.101 +    {
   4.102 +      entry->parent = parent;
   4.103 +      entry->prev = parent->last;
   4.104 +    }
   4.105 +  else
   4.106 +    {
   4.107 +      parent = root;
   4.108 +      entry->parent = root;
   4.109 +      entry->prev = root->last;
   4.110 +    }
   4.111 +
   4.112 +  pdf_set_dict_entry (entry->dict, "Parent", parent->dict);
   4.113 +
   4.114 +  if (entry->prev)
   4.115 +    {
   4.116 +      pdf_set_dict_entry (entry->dict, "Prev", entry->prev->dict);
   4.117 +
   4.118 +      entry->prev->next = entry;
   4.119 +      pdf_set_dict_entry (entry->prev->dict, "Next", entry->dict);
   4.120 +
   4.121 +      parent->last = entry;
   4.122 +      pdf_set_dict_entry (parent->dict, "Last", entry->dict);
   4.123 +    }
   4.124 +  else
   4.125 +    {
   4.126 +      parent->first = entry;
   4.127 +      pdf_set_dict_entry (parent->dict, "First", entry->dict);
   4.128 +
   4.129 +      parent->last = entry;
   4.130 +      pdf_set_dict_entry (parent->dict, "Last", entry->dict);
   4.131 +    }
   4.132 +
   4.133 +  pdf_bookmark_update_count (parent);
   4.134 +
   4.135 +  return (entry);
   4.136 +}
     5.1 diff -r 6e306105c128 -r 12bc5088172e pdf_prim.c
     5.2 --- a/pdf_prim.c	Wed Mar 05 01:58:31 2003 +0000
     5.3 +++ b/pdf_prim.c	Wed Mar 05 01:58:36 2003 +0000
     5.4 @@ -4,7 +4,7 @@
     5.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
     5.6   *
     5.7   * PDF routines
     5.8 - * $Id: pdf_prim.c,v 1.5 2003/02/21 02:49:11 eric Exp $
     5.9 + * $Id: pdf_prim.c,v 1.6 2003/03/04 17:58:36 eric Exp $
    5.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    5.11   *
    5.12   * This program is free software; you can redistribute it and/or modify
    5.13 @@ -102,7 +102,7 @@
    5.14      bool              boolean;
    5.15      char              *name;
    5.16      char              *string;
    5.17 -    unsigned long     integer;
    5.18 +    long              integer;
    5.19      double            real;
    5.20      struct pdf_obj    *ind_ref;
    5.21      struct pdf_dict   dict;
    5.22 @@ -233,7 +233,7 @@
    5.23  }
    5.24  
    5.25  
    5.26 -struct pdf_obj *pdf_new_integer (unsigned long val)
    5.27 +struct pdf_obj *pdf_new_integer (long val)
    5.28  {
    5.29    struct pdf_obj *obj = pdf_new_obj (PT_INTEGER);
    5.30    obj->val.integer = val;
    5.31 @@ -315,7 +315,7 @@
    5.32  }
    5.33  
    5.34  
    5.35 -unsigned long pdf_get_integer (struct pdf_obj *obj)
    5.36 +long pdf_get_integer (struct pdf_obj *obj)
    5.37  {
    5.38    if (obj->type == PT_IND_REF)
    5.39      obj = pdf_deref_ind_obj (obj);
    5.40 @@ -325,7 +325,7 @@
    5.41    return (obj->val.integer);
    5.42  }
    5.43  
    5.44 -void pdf_set_integer (struct pdf_obj *obj, unsigned long val)
    5.45 +void pdf_set_integer (struct pdf_obj *obj, long val)
    5.46  {
    5.47    if (obj->type == PT_IND_REF)
    5.48      obj = pdf_deref_ind_obj (obj);
     6.1 diff -r 6e306105c128 -r 12bc5088172e pdf_prim.h
     6.2 --- a/pdf_prim.h	Wed Mar 05 01:58:31 2003 +0000
     6.3 +++ b/pdf_prim.h	Wed Mar 05 01:58:36 2003 +0000
     6.4 @@ -4,7 +4,7 @@
     6.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
     6.6   *
     6.7   * PDF routines
     6.8 - * $Id: pdf_prim.h,v 1.4 2003/02/21 02:49:11 eric Exp $
     6.9 + * $Id: pdf_prim.h,v 1.5 2003/03/04 17:58:36 eric Exp $
    6.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    6.11   *
    6.12   * This program is free software; you can redistribute it and/or modify
    6.13 @@ -68,7 +68,7 @@
    6.14  
    6.15  struct pdf_obj *pdf_new_string (char *str);
    6.16  
    6.17 -struct pdf_obj *pdf_new_integer (unsigned long val);
    6.18 +struct pdf_obj *pdf_new_integer (long val);
    6.19  
    6.20  struct pdf_obj *pdf_new_real (double val);
    6.21  
    6.22 @@ -80,8 +80,8 @@
    6.23  struct pdf_obj *pdf_deref_ind_obj (struct pdf_obj *ind_obj);
    6.24  
    6.25  
    6.26 -unsigned long pdf_get_integer (struct pdf_obj *obj);
    6.27 -void pdf_set_integer (struct pdf_obj *obj, unsigned long val);
    6.28 +long pdf_get_integer (struct pdf_obj *obj);
    6.29 +void pdf_set_integer (struct pdf_obj *obj, long val);
    6.30  
    6.31  
    6.32  double pdf_get_real (struct pdf_obj *obj);
     7.1 diff -r 6e306105c128 -r 12bc5088172e pdf_private.h
     7.2 --- a/pdf_private.h	Wed Mar 05 01:58:31 2003 +0000
     7.3 +++ b/pdf_private.h	Wed Mar 05 01:58:36 2003 +0000
     7.4 @@ -4,7 +4,7 @@
     7.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
     7.6   *
     7.7   * PDF routines
     7.8 - * $Id: pdf_private.h,v 1.2 2003/02/20 04:44:17 eric Exp $
     7.9 + * $Id: pdf_private.h,v 1.3 2003/03/04 17:58:36 eric Exp $
    7.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    7.11   *
    7.12   * This program is free software; you can redistribute it and/or modify
    7.13 @@ -45,14 +45,32 @@
    7.14  };
    7.15  
    7.16  
    7.17 +struct pdf_bookmark
    7.18 +{
    7.19 +  struct pdf_obj *dict;    /* indirect reference */
    7.20 +  bool open;
    7.21 +
    7.22 +  struct pdf_bookmark *first;
    7.23 +  struct pdf_bookmark *last;
    7.24 +
    7.25 +  /* the following fields don't appear in the root */
    7.26 +  /* title and dest are in the dictionary but don't have
    7.27 +     explicit fields in the C structure */
    7.28 +  struct pdf_bookmark *parent;
    7.29 +  struct pdf_bookmark *prev;
    7.30 +  struct pdf_bookmark *next;
    7.31 +};
    7.32 +
    7.33 +
    7.34  struct pdf_file
    7.35  {
    7.36 -  FILE             *f;
    7.37 -  struct pdf_obj   *first_ind_obj;
    7.38 -  struct pdf_obj   *last_ind_obj;
    7.39 -  long int         xref_offset;
    7.40 -  struct pdf_obj   *catalog;
    7.41 -  struct pdf_obj   *info;
    7.42 -  struct pdf_pages *root;
    7.43 -  struct pdf_obj   *trailer_dict;
    7.44 +  FILE                *f;
    7.45 +  struct pdf_obj      *first_ind_obj;
    7.46 +  struct pdf_obj      *last_ind_obj;
    7.47 +  long int             xref_offset;
    7.48 +  struct pdf_obj      *catalog;
    7.49 +  struct pdf_obj      *info;
    7.50 +  struct pdf_pages    *root;
    7.51 +  struct pdf_bookmark *outline_root;
    7.52 +  struct pdf_obj      *trailer_dict;
    7.53  };
     8.1 diff -r 6e306105c128 -r 12bc5088172e pdf_util.h
     8.2 --- a/pdf_util.h	Wed Mar 05 01:58:31 2003 +0000
     8.3 +++ b/pdf_util.h	Wed Mar 05 01:58:36 2003 +0000
     8.4 @@ -4,7 +4,7 @@
     8.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
     8.6   *
     8.7   * PDF routines
     8.8 - * $Id: pdf_util.h,v 1.3 2003/02/21 02:49:11 eric Exp $
     8.9 + * $Id: pdf_util.h,v 1.4 2003/03/04 17:58:36 eric Exp $
    8.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    8.11   *
    8.12   * This program is free software; you can redistribute it and/or modify
    8.13 @@ -24,14 +24,21 @@
    8.14   */
    8.15  
    8.16  
    8.17 +#include <assert.h>
    8.18 +
    8.19 +
    8.20  void pdf_fatal (char *fmt, ...);
    8.21  
    8.22  void *pdf_calloc (size_t nmemb, size_t size);
    8.23  
    8.24  char *pdf_strdup (char *s);
    8.25  
    8.26 +#if 1
    8.27 +#define pdf_assert(cond) assert(cond)
    8.28 +#else
    8.29  #define pdf_assert(cond) do \
    8.30      { \
    8.31        if (! (cond)) \
    8.32          pdf_fatal ("assert at %s(%d)\n", __FILE__, __LINE__); \
    8.33      } while (0)
    8.34 +#endif
     9.1 diff -r 6e306105c128 -r 12bc5088172e t2p.c
     9.2 --- a/t2p.c	Wed Mar 05 01:58:31 2003 +0000
     9.3 +++ b/t2p.c	Wed Mar 05 01:58:36 2003 +0000
     9.4 @@ -4,7 +4,7 @@
     9.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
     9.6   *
     9.7   * Main program
     9.8 - * $Id: t2p.c,v 1.24 2003/02/21 01:25:47 eric Exp $
     9.9 + * $Id: t2p.c,v 1.25 2003/03/04 17:58:36 eric Exp $
    9.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    9.11   *
    9.12   * This program is free software; you can redistribute it and/or modify
    9.13 @@ -88,7 +88,7 @@
    9.14    fprintf (stderr, "    -v   verbose\n");
    9.15    fprintf (stderr, "    -b fmt  create bookmarks\n");
    9.16    fprintf (stderr, "bookmark format:\n");
    9.17 -  fprintf (stderr, "    %%F  file name\n");
    9.18 +  fprintf (stderr, "    %%F  file name (sans suffix)\n");
    9.19    fprintf (stderr, "    %%p  page number\n");
    9.20  }
    9.21  
    9.22 @@ -311,7 +311,7 @@
    9.23  					  points */
    9.24  
    9.25    Rect rect;
    9.26 -  Bitmap *bitmap;
    9.27 +  Bitmap *bitmap = NULL;
    9.28  
    9.29    int row;
    9.30  
    9.31 @@ -464,6 +464,7 @@
    9.32  
    9.33    page = pdf_new_page (out->pdf, width_points, height_points);
    9.34  
    9.35 +#if 0
    9.36    pdf_write_g4_fax_image (page,
    9.37  			  0, 0,  /* x, y */
    9.38  			  width_points, height_points,
    9.39 @@ -471,21 +472,102 @@
    9.40  			  0, /* ImageMask */
    9.41  			  0, 0, 0,  /* r, g, b */
    9.42  			  0); /* BlackIs1 */
    9.43 +#endif
    9.44  
    9.45 -  free_bitmap (bitmap);
    9.46 +  while (bookmarks)
    9.47 +    {
    9.48 +      /* $$$ need to handle level here */
    9.49 +      pdf_new_bookmark (NULL, bookmarks->name, 0, page);
    9.50 +      bookmarks = bookmarks->next;
    9.51 +    }
    9.52  
    9.53    result = 1;
    9.54  
    9.55   fail:
    9.56 +  if (bitmap)
    9.57 +    free_bitmap (bitmap);
    9.58 +
    9.59    return (result);
    9.60  }
    9.61  
    9.62  
    9.63 -void main_args (char *out_fn, int inf_count, char **in_fn)
    9.64 +#define MAX_BOOKMARK_NAME_LEN 500
    9.65 +
    9.66 +
    9.67 +static int filename_length_without_suffix (char *in_fn)
    9.68 +{
    9.69 +  char *p;
    9.70 +  int len = strlen (in_fn);
    9.71 +
    9.72 +  p = strrchr (in_fn, '.');
    9.73 +  if (p && ((strcasecmp (p, ".tif") == 0) ||
    9.74 +	    (strcasecmp (p, ".tiff") == 0)))
    9.75 +    return (p - in_fn);
    9.76 +  return (len);
    9.77 +}
    9.78 +
    9.79 +
    9.80 +/* $$$ this function should ensure that it doesn't overflow the name string! */
    9.81 +static void generate_bookmark_name (char *name,
    9.82 +				    char *bookmark_fmt, 
    9.83 +				    char *in_fn,
    9.84 +				    int page)
    9.85 +{
    9.86 +  bool meta = 0;
    9.87 +  int len;
    9.88 +
    9.89 +  while (*bookmark_fmt)
    9.90 +    {
    9.91 +      if (meta)
    9.92 +	{
    9.93 +	  meta = 0;
    9.94 +	  switch (*bookmark_fmt)
    9.95 +	    {
    9.96 +	    case '%':
    9.97 +	      *(name++) = '%';
    9.98 +	      break;
    9.99 +	    case 'F':
   9.100 +	      len = filename_length_without_suffix (in_fn);
   9.101 +	      strncpy (name, in_fn, len);
   9.102 +	      name += len;
   9.103 +	      break;
   9.104 +	    case 'p':
   9.105 +	      sprintf (name, "%d", page);
   9.106 +	      name += strlen (name);
   9.107 +	      break;
   9.108 +	    default:
   9.109 +	      break;
   9.110 +	    }
   9.111 +	}
   9.112 +      else
   9.113 +	switch (*bookmark_fmt)
   9.114 +	  {
   9.115 +	  case '%':
   9.116 +	    meta = 1;
   9.117 +	    break;
   9.118 +	  default:
   9.119 +	    *(name++) = *bookmark_fmt;
   9.120 +	  }
   9.121 +      bookmark_fmt++;
   9.122 +    }
   9.123 +  *bookmark_fmt = '\0';
   9.124 +}
   9.125 +
   9.126 +
   9.127 +void main_args (char *out_fn,
   9.128 +		int inf_count,
   9.129 +		char **in_fn,
   9.130 +		char *bookmark_fmt)
   9.131  {
   9.132    int i, ip;
   9.133    input_attributes_t input_attributes;
   9.134    pdf_file_attributes_t output_attributes;
   9.135 +  bookmark_t bookmark;
   9.136 +  char bookmark_name [MAX_BOOKMARK_NAME_LEN];
   9.137 +
   9.138 +  bookmark.next = NULL;
   9.139 +  bookmark.level = 1;
   9.140 +  bookmark.name = & bookmark_name [0];
   9.141  
   9.142    memset (& input_attributes, 0, sizeof (input_attributes));
   9.143    memset (& output_attributes, 0, sizeof (output_attributes));
   9.144 @@ -499,7 +581,13 @@
   9.145        for (ip = 1;; ip++)
   9.146  	{
   9.147  	  fprintf (stderr, "processing page %d of file \"%s\"\r", ip, in_fn [i]);
   9.148 -	  if (! process_page (ip, input_attributes, NULL))
   9.149 +	  if (bookmark_fmt)
   9.150 +	    generate_bookmark_name (& bookmark_name [0],
   9.151 +				    bookmark_fmt, 
   9.152 +				    in_fn [i],
   9.153 +				    ip);
   9.154 +	  if (! process_page (ip, input_attributes,
   9.155 +			      bookmark_fmt ? & bookmark : NULL))
   9.156  	    fatal (3, "error processing page %d of input file \"%s\"\n", ip, in_fn [i]);
   9.157  	  if (last_tiff_page ())
   9.158  	    break;
   9.159 @@ -596,7 +684,7 @@
   9.160    if (spec_fn)
   9.161      main_spec (spec_fn);
   9.162    else
   9.163 -    main_args (out_fn, inf_count, in_fn);
   9.164 +    main_args (out_fn, inf_count, in_fn, bookmark_fmt);
   9.165    
   9.166    close_tiff_input_file ();
   9.167    close_pdf_output_files ();
    10.1 diff -r 6e306105c128 -r 12bc5088172e tumble.c
    10.2 --- a/tumble.c	Wed Mar 05 01:58:31 2003 +0000
    10.3 +++ b/tumble.c	Wed Mar 05 01:58:36 2003 +0000
    10.4 @@ -4,7 +4,7 @@
    10.5   *      will be compressed using ITU-T T.6 (G4) fax encoding.
    10.6   *
    10.7   * Main program
    10.8 - * $Id: tumble.c,v 1.24 2003/02/21 01:25:47 eric Exp $
    10.9 + * $Id: tumble.c,v 1.25 2003/03/04 17:58:36 eric Exp $
   10.10   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
   10.11   *
   10.12   * This program is free software; you can redistribute it and/or modify
   10.13 @@ -88,7 +88,7 @@
   10.14    fprintf (stderr, "    -v   verbose\n");
   10.15    fprintf (stderr, "    -b fmt  create bookmarks\n");
   10.16    fprintf (stderr, "bookmark format:\n");
   10.17 -  fprintf (stderr, "    %%F  file name\n");
   10.18 +  fprintf (stderr, "    %%F  file name (sans suffix)\n");
   10.19    fprintf (stderr, "    %%p  page number\n");
   10.20  }
   10.21  
   10.22 @@ -311,7 +311,7 @@
   10.23  					  points */
   10.24  
   10.25    Rect rect;
   10.26 -  Bitmap *bitmap;
   10.27 +  Bitmap *bitmap = NULL;
   10.28  
   10.29    int row;
   10.30  
   10.31 @@ -464,6 +464,7 @@
   10.32  
   10.33    page = pdf_new_page (out->pdf, width_points, height_points);
   10.34  
   10.35 +#if 0
   10.36    pdf_write_g4_fax_image (page,
   10.37  			  0, 0,  /* x, y */
   10.38  			  width_points, height_points,
   10.39 @@ -471,21 +472,102 @@
   10.40  			  0, /* ImageMask */
   10.41  			  0, 0, 0,  /* r, g, b */
   10.42  			  0); /* BlackIs1 */
   10.43 +#endif
   10.44  
   10.45 -  free_bitmap (bitmap);
   10.46 +  while (bookmarks)
   10.47 +    {
   10.48 +      /* $$$ need to handle level here */
   10.49 +      pdf_new_bookmark (NULL, bookmarks->name, 0, page);
   10.50 +      bookmarks = bookmarks->next;
   10.51 +    }
   10.52  
   10.53    result = 1;
   10.54  
   10.55   fail:
   10.56 +  if (bitmap)
   10.57 +    free_bitmap (bitmap);
   10.58 +
   10.59    return (result);
   10.60  }
   10.61  
   10.62  
   10.63 -void main_args (char *out_fn, int inf_count, char **in_fn)
   10.64 +#define MAX_BOOKMARK_NAME_LEN 500
   10.65 +
   10.66 +
   10.67 +static int filename_length_without_suffix (char *in_fn)
   10.68 +{
   10.69 +  char *p;
   10.70 +  int len = strlen (in_fn);
   10.71 +
   10.72 +  p = strrchr (in_fn, '.');
   10.73 +  if (p && ((strcasecmp (p, ".tif") == 0) ||
   10.74 +	    (strcasecmp (p, ".tiff") == 0)))
   10.75 +    return (p - in_fn);
   10.76 +  return (len);
   10.77 +}
   10.78 +
   10.79 +
   10.80 +/* $$$ this function should ensure that it doesn't overflow the name string! */
   10.81 +static void generate_bookmark_name (char *name,
   10.82 +				    char *bookmark_fmt, 
   10.83 +				    char *in_fn,
   10.84 +				    int page)
   10.85 +{
   10.86 +  bool meta = 0;
   10.87 +  int len;
   10.88 +
   10.89 +  while (*bookmark_fmt)
   10.90 +    {
   10.91 +      if (meta)
   10.92 +	{
   10.93 +	  meta = 0;
   10.94 +	  switch (*bookmark_fmt)
   10.95 +	    {
   10.96 +	    case '%':
   10.97 +	      *(name++) = '%';
   10.98 +	      break;
   10.99 +	    case 'F':
  10.100 +	      len = filename_length_without_suffix (in_fn);
  10.101 +	      strncpy (name, in_fn, len);
  10.102 +	      name += len;
  10.103 +	      break;
  10.104 +	    case 'p':
  10.105 +	      sprintf (name, "%d", page);
  10.106 +	      name += strlen (name);
  10.107 +	      break;
  10.108 +	    default:
  10.109 +	      break;
  10.110 +	    }
  10.111 +	}
  10.112 +      else
  10.113 +	switch (*bookmark_fmt)
  10.114 +	  {
  10.115 +	  case '%':
  10.116 +	    meta = 1;
  10.117 +	    break;
  10.118 +	  default:
  10.119 +	    *(name++) = *bookmark_fmt;
  10.120 +	  }
  10.121 +      bookmark_fmt++;
  10.122 +    }
  10.123 +  *bookmark_fmt = '\0';
  10.124 +}
  10.125 +
  10.126 +
  10.127 +void main_args (char *out_fn,
  10.128 +		int inf_count,
  10.129 +		char **in_fn,
  10.130 +		char *bookmark_fmt)
  10.131  {
  10.132    int i, ip;
  10.133    input_attributes_t input_attributes;
  10.134    pdf_file_attributes_t output_attributes;
  10.135 +  bookmark_t bookmark;
  10.136 +  char bookmark_name [MAX_BOOKMARK_NAME_LEN];
  10.137 +
  10.138 +  bookmark.next = NULL;
  10.139 +  bookmark.level = 1;
  10.140 +  bookmark.name = & bookmark_name [0];
  10.141  
  10.142    memset (& input_attributes, 0, sizeof (input_attributes));
  10.143    memset (& output_attributes, 0, sizeof (output_attributes));
  10.144 @@ -499,7 +581,13 @@
  10.145        for (ip = 1;; ip++)
  10.146  	{
  10.147  	  fprintf (stderr, "processing page %d of file \"%s\"\r", ip, in_fn [i]);
  10.148 -	  if (! process_page (ip, input_attributes, NULL))
  10.149 +	  if (bookmark_fmt)
  10.150 +	    generate_bookmark_name (& bookmark_name [0],
  10.151 +				    bookmark_fmt, 
  10.152 +				    in_fn [i],
  10.153 +				    ip);
  10.154 +	  if (! process_page (ip, input_attributes,
  10.155 +			      bookmark_fmt ? & bookmark : NULL))
  10.156  	    fatal (3, "error processing page %d of input file \"%s\"\n", ip, in_fn [i]);
  10.157  	  if (last_tiff_page ())
  10.158  	    break;
  10.159 @@ -596,7 +684,7 @@
  10.160    if (spec_fn)
  10.161      main_spec (spec_fn);
  10.162    else
  10.163 -    main_args (out_fn, inf_count, in_fn);
  10.164 +    main_args (out_fn, inf_count, in_fn, bookmark_fmt);
  10.165    
  10.166    close_tiff_input_file ();
  10.167    close_pdf_output_files ();