my own PDF routines to replace Panda.

Thu, 20 Feb 2003 12:16:00 +0000

author
eric
date
Thu, 20 Feb 2003 12:16:00 +0000
changeset 59
e8821eb2fb08
parent 58
d1c6dc4bf34a
child 60
ffb5b1e54eb2

my own PDF routines to replace Panda.

bitblt_g4.c file | annotate | diff | revisions
pdf.c file | annotate | diff | revisions
pdf.h file | annotate | diff | revisions
pdf_g4.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.c file | annotate | diff | revisions
pdf_util.h file | annotate | diff | revisions
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/bitblt_g4.c	Thu Feb 20 12:16:00 2003 +0000
     1.3 @@ -0,0 +1,179 @@
     1.4 +#include <stdio.h>
     1.5 +#include <string.h>
     1.6 +
     1.7 +
     1.8 +#include "libpdf.h"
     1.9 +#include "libpdf_util.h"
    1.10 +#include "libpdf_prim.h"
    1.11 +#include "libpdf_private.h"
    1.12 +
    1.13 +
    1.14 +struct pdf_g4_image
    1.15 +{
    1.16 +  unsigned long Columns;
    1.17 +  unsigned long Rows;
    1.18 +  unsigned long rowbytes;
    1.19 +  int BlackIs1;
    1.20 +  unsigned char *data;
    1.21 +  unsigned long len;
    1.22 +  char XObject_name [4];
    1.23 +};
    1.24 +
    1.25 +
    1.26 +char pdf_new_XObject (pdf_page_handle pdf_page, struct pdf_obj *ind_ref)
    1.27 +{
    1.28 +  char XObject_name [4] = "Im ";
    1.29 +
    1.30 +  XObject_name [2] = ++pdf_page->last_XObject_name;
    1.31 +  
    1.32 +  if (! pdf_page->XObject_dict)
    1.33 +    {
    1.34 +      pdf_page->XObject_dict = pdf_new_obj (PT_DICTIONARY);
    1.35 +      pdf_set_dict_entry (pdf_page->resources, "XObject", pdf_page->XObject_dict);
    1.36 +    }
    1.37 +
    1.38 +  pdf_set_dict_entry (pdf_page->XObject_dict, & XObject_name [0], ind_ref);
    1.39 +
    1.40 +  return (pdf_page->last_XObject_name);
    1.41 +}
    1.42 +
    1.43 +
    1.44 +void pdf_write_g4_content_callback (pdf_file_handle pdf_file,
    1.45 +				    struct pdf_obj *stream,
    1.46 +				    void *app_data)
    1.47 +{
    1.48 +  unsigned long width = (8.5 * 72);  /* full width of page */
    1.49 +  unsigned long height = (11 * 72);  /* full height of page */
    1.50 +  unsigned long x = 0;  /* 0 is left edge */
    1.51 +  unsigned long y = 0;  /* 0 is bottom edge */
    1.52 +  struct pdf_g4_image *image = app_data;
    1.53 +
    1.54 +  char str1 [100];
    1.55 +  char *str2 = "/";
    1.56 +  char *str3 = " Do\r\n";
    1.57 +
    1.58 +  /* width 0 0 height x y cm */
    1.59 +  sprintf (str1, "q %ld 0 0 %ld %ld %ld cm\r\n", width, height, x, y);
    1.60 +
    1.61 +  pdf_stream_write_data (pdf_file, stream, str1, strlen (str1));
    1.62 +  pdf_stream_write_data (pdf_file, stream, str2, strlen (str2));
    1.63 +  pdf_stream_write_data (pdf_file, stream, & image->XObject_name [0],
    1.64 +			 strlen (& image->XObject_name [0]));
    1.65 +  pdf_stream_write_data (pdf_file, stream, str3, strlen (str3));
    1.66 +}
    1.67 +
    1.68 +
    1.69 +void pdf_write_g4_fax_image_callback (pdf_file_handle pdf_file,
    1.70 +				      struct pdf_obj *stream,
    1.71 +				      void *app_data)
    1.72 +{
    1.73 +  struct pdf_g4_image *image = app_data;
    1.74 +
    1.75 +#if 1
    1.76 +  pdf_stream_write_data (pdf_file, stream, image->data, image->len);
    1.77 +#else
    1.78 +  unsigned long row = 0;
    1.79 +  unsigned char *ref;
    1.80 +  unsigned char *raw;
    1.81 +
    1.82 +  ref = NULL;
    1.83 +  raw = image->data;
    1.84 +
    1.85 +  while (row < image->Rows)
    1.86 +    {
    1.87 +      pdf_stream_write_data (pdf_file, stream, raw, image->rowbytes);
    1.88 +
    1.89 +      row++;
    1.90 +      ref = raw;
    1.91 +      raw += image->rowbytes;
    1.92 +    }
    1.93 +  /* $$$ generate and write EOFB code */
    1.94 +  /* $$$ flush any remaining buffered bits */
    1.95 +#endif
    1.96 +}
    1.97 +
    1.98 +
    1.99 +void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
   1.100 +			     unsigned long Columns,
   1.101 +			     unsigned long Rows,
   1.102 +			     unsigned long rowbytes,
   1.103 +			     int ImageMask,
   1.104 +			     int BlackIs1,          /* boolean, typ. false */
   1.105 +			     unsigned char *data,
   1.106 +			     unsigned long len)
   1.107 +{
   1.108 +  struct pdf_g4_image *image;
   1.109 +
   1.110 +  struct pdf_obj *stream;
   1.111 +  struct pdf_obj *stream_dict;
   1.112 +  struct pdf_obj *decode_parms;
   1.113 +
   1.114 +  struct pdf_obj *content_stream;
   1.115 +
   1.116 +  image = pdf_calloc (sizeof (struct pdf_g4_image));
   1.117 +
   1.118 +  image->Columns = Columns;
   1.119 +  image->Rows = Rows;
   1.120 +  image->rowbytes = rowbytes;
   1.121 +  image->BlackIs1 = BlackIs1;
   1.122 +  image->data = data;
   1.123 +  image->len = len;
   1.124 +
   1.125 +  stream_dict = pdf_new_obj (PT_DICTIONARY);
   1.126 +
   1.127 +  stream = pdf_new_ind_ref (pdf_page->pdf_file,
   1.128 +			    pdf_new_stream (pdf_page->pdf_file,
   1.129 +					    stream_dict,
   1.130 +					    & pdf_write_g4_fax_image_callback,
   1.131 +					    image));
   1.132 +
   1.133 +  strcpy (& image->XObject_name [0], "Im ");
   1.134 +  image->XObject_name [2] = pdf_new_XObject (pdf_page, stream);
   1.135 +
   1.136 +  pdf_set_dict_entry (stream_dict, "Type",    pdf_new_name ("XObject"));
   1.137 +  pdf_set_dict_entry (stream_dict, "Subtype", pdf_new_name ("Image"));
   1.138 +  pdf_set_dict_entry (stream_dict, "Name",    pdf_new_name (& image->XObject_name [0]));
   1.139 +  pdf_set_dict_entry (stream_dict, "Width",   pdf_new_integer (Columns));
   1.140 +  pdf_set_dict_entry (stream_dict, "Height",  pdf_new_integer (Rows));
   1.141 +  pdf_set_dict_entry (stream_dict, "BitsPerComponent", pdf_new_integer (1));
   1.142 +  if (ImageMask)
   1.143 +    pdf_set_dict_entry (stream_dict, "ImageMask", pdf_new_bool (ImageMask));
   1.144 +  else
   1.145 +    pdf_set_dict_entry (stream_dict, "ColorSpace", pdf_new_name ("DeviceGray"));
   1.146 +
   1.147 +  decode_parms = pdf_new_obj (PT_DICTIONARY);
   1.148 +
   1.149 +  pdf_set_dict_entry (decode_parms,
   1.150 +		      "K",
   1.151 +		      pdf_new_integer (-1));
   1.152 +
   1.153 +  pdf_set_dict_entry (decode_parms,
   1.154 +		      "Columns",
   1.155 +		      pdf_new_integer (Columns));
   1.156 +
   1.157 +  pdf_set_dict_entry (decode_parms,
   1.158 +		      "Rows",
   1.159 +		      pdf_new_integer (Rows));
   1.160 +
   1.161 +  if (BlackIs1)
   1.162 +    pdf_set_dict_entry (decode_parms,
   1.163 +			"BlackIs1",
   1.164 +			pdf_new_bool (BlackIs1));
   1.165 +
   1.166 +  pdf_stream_add_filter (stream, "CCITTFaxDecode", decode_parms);
   1.167 +
   1.168 +  /* the following will write the stream, using our callback function to
   1.169 +     get the actual data */
   1.170 +  pdf_write_ind_obj (pdf_page->pdf_file, stream);
   1.171 +
   1.172 +  content_stream = pdf_new_ind_ref (pdf_page->pdf_file,
   1.173 +				    pdf_new_stream (pdf_page->pdf_file,
   1.174 +						    pdf_new_obj (PT_DICTIONARY),
   1.175 +						    & pdf_write_g4_content_callback,
   1.176 +						    image));
   1.177 +
   1.178 +  pdf_set_dict_entry (pdf_page->page_dict, "Contents", content_stream);
   1.179 +
   1.180 +  pdf_write_ind_obj (pdf_page->pdf_file, content_stream);
   1.181 +}
   1.182 +
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/pdf.c	Thu Feb 20 12:16:00 2003 +0000
     2.3 @@ -0,0 +1,171 @@
     2.4 +#include <stdio.h>
     2.5 +#include <stdlib.h>
     2.6 +
     2.7 +
     2.8 +#include "libpdf.h"
     2.9 +#include "libpdf_util.h"
    2.10 +#include "libpdf_prim.h"
    2.11 +#include "libpdf_private.h"
    2.12 +
    2.13 +
    2.14 +static void pdf_set_info (pdf_file_handle pdf_file, char *key, char *val)
    2.15 +{
    2.16 +  if (! pdf_file->info)
    2.17 +    pdf_file->info = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
    2.18 +
    2.19 +  pdf_set_dict_entry (pdf_file->info, key, pdf_new_string (val));
    2.20 +}
    2.21 +
    2.22 +
    2.23 +void pdf_init (void)
    2.24 +{
    2.25 +}
    2.26 +
    2.27 +
    2.28 +struct pdf_pages *pdf_new_pages (pdf_file_handle pdf_file)
    2.29 +{
    2.30 +  struct pdf_pages *pages = pdf_calloc (sizeof (struct pdf_pages));
    2.31 +  pages->kids = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_ARRAY));
    2.32 +  pages->count = pdf_new_integer (0);
    2.33 +  pages->pages_dict = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
    2.34 +  pdf_set_dict_entry (pages->pages_dict, "Type", pdf_new_name ("Pages"));
    2.35 +  pdf_set_dict_entry (pages->pages_dict, "Kids", pages->kids);
    2.36 +  pdf_set_dict_entry (pages->pages_dict, "Count", pages->count);
    2.37 +  return (pages);
    2.38 +}
    2.39 +
    2.40 +
    2.41 +pdf_file_handle pdf_create (char *filename)
    2.42 +{
    2.43 +  pdf_file_handle pdf_file;
    2.44 +
    2.45 +  pdf_file = pdf_calloc (sizeof (struct pdf_file));
    2.46 +
    2.47 +  pdf_file->f = fopen (filename, "wb");
    2.48 +  if (! pdf_file->f)
    2.49 +    {
    2.50 +      pdf_fatal ("error opening output file\n");
    2.51 +    }
    2.52 +
    2.53 +  pdf_file->root = pdf_new_pages (pdf_file);
    2.54 +
    2.55 +  pdf_file->catalog = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
    2.56 +  pdf_set_dict_entry (pdf_file->catalog, "Type", pdf_new_name ("Catalog"));
    2.57 +  pdf_set_dict_entry (pdf_file->catalog, "Pages", pdf_file->root->pages_dict);
    2.58 +  /* Outlines dictionary will be created later if needed*/
    2.59 +  pdf_set_dict_entry (pdf_file->catalog, "PageMode", pdf_new_name ("UseNone"));
    2.60 +
    2.61 +  pdf_file->info    = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
    2.62 +  pdf_set_info (pdf_file, "Producer", "libpdf, Copyright 2003 Eric Smith <eric@brouhaha.com>");
    2.63 +
    2.64 +  pdf_file->trailer_dict = pdf_new_obj (PT_DICTIONARY);
    2.65 +  /* Size key will be added later */
    2.66 +  pdf_set_dict_entry (pdf_file->trailer_dict, "Root", pdf_file->catalog);
    2.67 +  pdf_set_dict_entry (pdf_file->trailer_dict, "Info", pdf_file->info);
    2.68 +
    2.69 +  /* write file header */
    2.70 +  fprintf (pdf_file->f, "%%PDF-1.2\r\n");
    2.71 +
    2.72 +  return (pdf_file);
    2.73 +}
    2.74 +
    2.75 +
    2.76 +void pdf_close (pdf_file_handle pdf_file)
    2.77 +{
    2.78 +  /* write body */
    2.79 +  pdf_write_all_ind_obj (pdf_file);
    2.80 +
    2.81 +  /* write cross reference table and get maximum object number */
    2.82 +  pdf_set_dict_entry (pdf_file->trailer_dict, "Size", pdf_new_integer (pdf_write_xref (pdf_file)));
    2.83 +
    2.84 +  /* write trailer */
    2.85 +  fprintf (pdf_file->f, "trailer\r\n");
    2.86 +  pdf_write_obj (pdf_file, pdf_file->trailer_dict);
    2.87 +  fprintf (pdf_file->f, "startxref\r\n");
    2.88 +  fprintf (pdf_file->f, "%ld\r\n", pdf_file->xref_offset);
    2.89 +  fprintf (pdf_file->f, "%%%%EOF\r\n");
    2.90 +
    2.91 +  fclose (pdf_file->f);
    2.92 +  /* should free stuff here */
    2.93 +}
    2.94 +
    2.95 +
    2.96 +void pdf_set_author   (pdf_file_handle pdf_file, char *author)
    2.97 +{
    2.98 +  pdf_set_info (pdf_file, "Author", author);
    2.99 +}
   2.100 +
   2.101 +void pdf_set_creator  (pdf_file_handle pdf_file, char *creator)
   2.102 +{
   2.103 +  pdf_set_info (pdf_file, "Creator", creator);
   2.104 +}
   2.105 +
   2.106 +void pdf_set_producer  (pdf_file_handle pdf_file, char *producer)
   2.107 +{
   2.108 +  pdf_set_info (pdf_file, "Producer", producer);
   2.109 +}
   2.110 +
   2.111 +void pdf_set_title    (pdf_file_handle pdf_file, char *title)
   2.112 +{
   2.113 +  pdf_set_info (pdf_file, "Title", title);
   2.114 +}
   2.115 +
   2.116 +void pdf_set_subject  (pdf_file_handle pdf_file, char *subject)
   2.117 +{
   2.118 +  pdf_set_info (pdf_file, "Subject", subject);
   2.119 +}
   2.120 +
   2.121 +void pdf_set_keywords (pdf_file_handle pdf_file, char *keywords)
   2.122 +{
   2.123 +  pdf_set_info (pdf_file, "Keywords", keywords);
   2.124 +}
   2.125 +
   2.126 +
   2.127 +pdf_page_handle pdf_new_page (pdf_file_handle pdf_file,
   2.128 +			      double width,
   2.129 +			      double height)
   2.130 +{
   2.131 +  pdf_page_handle page = pdf_calloc (sizeof (struct pdf_page));
   2.132 +
   2.133 +  page->pdf_file = pdf_file;
   2.134 +
   2.135 +  page->media_box = pdf_new_obj (PT_ARRAY);
   2.136 +  pdf_add_array_elem (page->media_box, pdf_new_real (0));
   2.137 +  pdf_add_array_elem (page->media_box, pdf_new_real (0));
   2.138 +  pdf_add_array_elem (page->media_box, pdf_new_real (width));
   2.139 +  pdf_add_array_elem (page->media_box, pdf_new_real (height));
   2.140 +
   2.141 +  page->procset = pdf_new_obj (PT_ARRAY);
   2.142 +  pdf_add_array_elem (page->procset, pdf_new_name ("PDF"));
   2.143 +
   2.144 +  page->resources = pdf_new_obj (PT_DICTIONARY);
   2.145 +  pdf_set_dict_entry (page->resources, "ProcSet", page->procset);
   2.146 +
   2.147 +  page->page_dict = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
   2.148 +  pdf_set_dict_entry (page->page_dict, "Type", pdf_new_name ("Page"));
   2.149 +  pdf_set_dict_entry (page->page_dict, "MediaBox", page->media_box);
   2.150 +  pdf_set_dict_entry (page->page_dict, "Resources", page->resources);
   2.151 +
   2.152 +  /* $$$ currently only support a single-level pages tree */
   2.153 +  pdf_set_dict_entry (page->page_dict, "Parent", pdf_file->root->pages_dict);
   2.154 +  pdf_add_array_elem (pdf_file->root->kids, page->page_dict);
   2.155 +  pdf_set_integer (pdf_file->root->count,
   2.156 +		   pdf_get_integer (pdf_file->root->count) + 1);
   2.157 +
   2.158 +  page->last_XObject_name = '@';  /* first name will be "ImA" */
   2.159 +
   2.160 +  return (page);
   2.161 +}
   2.162 +
   2.163 +void pdf_close_page (pdf_page_handle pdf_page)
   2.164 +{
   2.165 +}
   2.166 +
   2.167 +
   2.168 +void pdf_set_page_number (pdf_page_handle pdf_page, char *page_number)
   2.169 +{
   2.170 +}
   2.171 +
   2.172 +void pdf_bookmark (pdf_page_handle pdf_page, int level, char *name)
   2.173 +{
   2.174 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/pdf.h	Thu Feb 20 12:16:00 2003 +0000
     3.3 @@ -0,0 +1,44 @@
     3.4 +typedef struct pdf_file *pdf_file_handle;
     3.5 +
     3.6 +typedef struct pdf_page *pdf_page_handle;
     3.7 +
     3.8 +
     3.9 +void pdf_init (void);
    3.10 +
    3.11 +pdf_file_handle pdf_create (char *filename);
    3.12 +
    3.13 +void pdf_close (pdf_file_handle pdf_file);
    3.14 +
    3.15 +void pdf_set_author   (pdf_file_handle pdf_file, char *author);
    3.16 +void pdf_set_creator  (pdf_file_handle pdf_file, char *author);
    3.17 +void pdf_set_title    (pdf_file_handle pdf_file, char *author);
    3.18 +void pdf_set_subject  (pdf_file_handle pdf_file, char *author);
    3.19 +void pdf_set_keywords (pdf_file_handle pdf_file, char *author);
    3.20 +
    3.21 +
    3.22 +/* width and height in units of 1/72 inch */
    3.23 +pdf_page_handle pdf_new_page (pdf_file_handle pdf_file,
    3.24 +			      double width,
    3.25 +			      double height);
    3.26 +
    3.27 +void pdf_close_page (pdf_page_handle pdf_page);
    3.28 +
    3.29 +
    3.30 +/* The length of the data must be Rows * rowbytes.
    3.31 +   Note that rowbytes must be at least (Columns+7)/8, but may be arbitrarily
    3.32 +   large. */
    3.33 +void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
    3.34 +			     unsigned long Columns,
    3.35 +			     unsigned long Rows,
    3.36 +			     unsigned long rowbytes,
    3.37 +			     int ImageMask,
    3.38 +			     int BlackIs1,          /* boolean, typ. false */
    3.39 +			     unsigned char *data,
    3.40 +			     unsigned long len);
    3.41 +
    3.42 +
    3.43 +void pdf_set_page_number (pdf_page_handle pdf_page, char *page_number);
    3.44 +
    3.45 +void pdf_bookmark (pdf_page_handle pdf_page, int level, char *name);
    3.46 +
    3.47 +void pdf_insert_tiff_image (pdf_page_handle pdf_page, char *filename);
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/pdf_g4.c	Thu Feb 20 12:16:00 2003 +0000
     4.3 @@ -0,0 +1,179 @@
     4.4 +#include <stdio.h>
     4.5 +#include <string.h>
     4.6 +
     4.7 +
     4.8 +#include "libpdf.h"
     4.9 +#include "libpdf_util.h"
    4.10 +#include "libpdf_prim.h"
    4.11 +#include "libpdf_private.h"
    4.12 +
    4.13 +
    4.14 +struct pdf_g4_image
    4.15 +{
    4.16 +  unsigned long Columns;
    4.17 +  unsigned long Rows;
    4.18 +  unsigned long rowbytes;
    4.19 +  int BlackIs1;
    4.20 +  unsigned char *data;
    4.21 +  unsigned long len;
    4.22 +  char XObject_name [4];
    4.23 +};
    4.24 +
    4.25 +
    4.26 +char pdf_new_XObject (pdf_page_handle pdf_page, struct pdf_obj *ind_ref)
    4.27 +{
    4.28 +  char XObject_name [4] = "Im ";
    4.29 +
    4.30 +  XObject_name [2] = ++pdf_page->last_XObject_name;
    4.31 +  
    4.32 +  if (! pdf_page->XObject_dict)
    4.33 +    {
    4.34 +      pdf_page->XObject_dict = pdf_new_obj (PT_DICTIONARY);
    4.35 +      pdf_set_dict_entry (pdf_page->resources, "XObject", pdf_page->XObject_dict);
    4.36 +    }
    4.37 +
    4.38 +  pdf_set_dict_entry (pdf_page->XObject_dict, & XObject_name [0], ind_ref);
    4.39 +
    4.40 +  return (pdf_page->last_XObject_name);
    4.41 +}
    4.42 +
    4.43 +
    4.44 +void pdf_write_g4_content_callback (pdf_file_handle pdf_file,
    4.45 +				    struct pdf_obj *stream,
    4.46 +				    void *app_data)
    4.47 +{
    4.48 +  unsigned long width = (8.5 * 72);  /* full width of page */
    4.49 +  unsigned long height = (11 * 72);  /* full height of page */
    4.50 +  unsigned long x = 0;  /* 0 is left edge */
    4.51 +  unsigned long y = 0;  /* 0 is bottom edge */
    4.52 +  struct pdf_g4_image *image = app_data;
    4.53 +
    4.54 +  char str1 [100];
    4.55 +  char *str2 = "/";
    4.56 +  char *str3 = " Do\r\n";
    4.57 +
    4.58 +  /* width 0 0 height x y cm */
    4.59 +  sprintf (str1, "q %ld 0 0 %ld %ld %ld cm\r\n", width, height, x, y);
    4.60 +
    4.61 +  pdf_stream_write_data (pdf_file, stream, str1, strlen (str1));
    4.62 +  pdf_stream_write_data (pdf_file, stream, str2, strlen (str2));
    4.63 +  pdf_stream_write_data (pdf_file, stream, & image->XObject_name [0],
    4.64 +			 strlen (& image->XObject_name [0]));
    4.65 +  pdf_stream_write_data (pdf_file, stream, str3, strlen (str3));
    4.66 +}
    4.67 +
    4.68 +
    4.69 +void pdf_write_g4_fax_image_callback (pdf_file_handle pdf_file,
    4.70 +				      struct pdf_obj *stream,
    4.71 +				      void *app_data)
    4.72 +{
    4.73 +  struct pdf_g4_image *image = app_data;
    4.74 +
    4.75 +#if 1
    4.76 +  pdf_stream_write_data (pdf_file, stream, image->data, image->len);
    4.77 +#else
    4.78 +  unsigned long row = 0;
    4.79 +  unsigned char *ref;
    4.80 +  unsigned char *raw;
    4.81 +
    4.82 +  ref = NULL;
    4.83 +  raw = image->data;
    4.84 +
    4.85 +  while (row < image->Rows)
    4.86 +    {
    4.87 +      pdf_stream_write_data (pdf_file, stream, raw, image->rowbytes);
    4.88 +
    4.89 +      row++;
    4.90 +      ref = raw;
    4.91 +      raw += image->rowbytes;
    4.92 +    }
    4.93 +  /* $$$ generate and write EOFB code */
    4.94 +  /* $$$ flush any remaining buffered bits */
    4.95 +#endif
    4.96 +}
    4.97 +
    4.98 +
    4.99 +void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
   4.100 +			     unsigned long Columns,
   4.101 +			     unsigned long Rows,
   4.102 +			     unsigned long rowbytes,
   4.103 +			     int ImageMask,
   4.104 +			     int BlackIs1,          /* boolean, typ. false */
   4.105 +			     unsigned char *data,
   4.106 +			     unsigned long len)
   4.107 +{
   4.108 +  struct pdf_g4_image *image;
   4.109 +
   4.110 +  struct pdf_obj *stream;
   4.111 +  struct pdf_obj *stream_dict;
   4.112 +  struct pdf_obj *decode_parms;
   4.113 +
   4.114 +  struct pdf_obj *content_stream;
   4.115 +
   4.116 +  image = pdf_calloc (sizeof (struct pdf_g4_image));
   4.117 +
   4.118 +  image->Columns = Columns;
   4.119 +  image->Rows = Rows;
   4.120 +  image->rowbytes = rowbytes;
   4.121 +  image->BlackIs1 = BlackIs1;
   4.122 +  image->data = data;
   4.123 +  image->len = len;
   4.124 +
   4.125 +  stream_dict = pdf_new_obj (PT_DICTIONARY);
   4.126 +
   4.127 +  stream = pdf_new_ind_ref (pdf_page->pdf_file,
   4.128 +			    pdf_new_stream (pdf_page->pdf_file,
   4.129 +					    stream_dict,
   4.130 +					    & pdf_write_g4_fax_image_callback,
   4.131 +					    image));
   4.132 +
   4.133 +  strcpy (& image->XObject_name [0], "Im ");
   4.134 +  image->XObject_name [2] = pdf_new_XObject (pdf_page, stream);
   4.135 +
   4.136 +  pdf_set_dict_entry (stream_dict, "Type",    pdf_new_name ("XObject"));
   4.137 +  pdf_set_dict_entry (stream_dict, "Subtype", pdf_new_name ("Image"));
   4.138 +  pdf_set_dict_entry (stream_dict, "Name",    pdf_new_name (& image->XObject_name [0]));
   4.139 +  pdf_set_dict_entry (stream_dict, "Width",   pdf_new_integer (Columns));
   4.140 +  pdf_set_dict_entry (stream_dict, "Height",  pdf_new_integer (Rows));
   4.141 +  pdf_set_dict_entry (stream_dict, "BitsPerComponent", pdf_new_integer (1));
   4.142 +  if (ImageMask)
   4.143 +    pdf_set_dict_entry (stream_dict, "ImageMask", pdf_new_bool (ImageMask));
   4.144 +  else
   4.145 +    pdf_set_dict_entry (stream_dict, "ColorSpace", pdf_new_name ("DeviceGray"));
   4.146 +
   4.147 +  decode_parms = pdf_new_obj (PT_DICTIONARY);
   4.148 +
   4.149 +  pdf_set_dict_entry (decode_parms,
   4.150 +		      "K",
   4.151 +		      pdf_new_integer (-1));
   4.152 +
   4.153 +  pdf_set_dict_entry (decode_parms,
   4.154 +		      "Columns",
   4.155 +		      pdf_new_integer (Columns));
   4.156 +
   4.157 +  pdf_set_dict_entry (decode_parms,
   4.158 +		      "Rows",
   4.159 +		      pdf_new_integer (Rows));
   4.160 +
   4.161 +  if (BlackIs1)
   4.162 +    pdf_set_dict_entry (decode_parms,
   4.163 +			"BlackIs1",
   4.164 +			pdf_new_bool (BlackIs1));
   4.165 +
   4.166 +  pdf_stream_add_filter (stream, "CCITTFaxDecode", decode_parms);
   4.167 +
   4.168 +  /* the following will write the stream, using our callback function to
   4.169 +     get the actual data */
   4.170 +  pdf_write_ind_obj (pdf_page->pdf_file, stream);
   4.171 +
   4.172 +  content_stream = pdf_new_ind_ref (pdf_page->pdf_file,
   4.173 +				    pdf_new_stream (pdf_page->pdf_file,
   4.174 +						    pdf_new_obj (PT_DICTIONARY),
   4.175 +						    & pdf_write_g4_content_callback,
   4.176 +						    image));
   4.177 +
   4.178 +  pdf_set_dict_entry (pdf_page->page_dict, "Contents", content_stream);
   4.179 +
   4.180 +  pdf_write_ind_obj (pdf_page->pdf_file, content_stream);
   4.181 +}
   4.182 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/pdf_prim.c	Thu Feb 20 12:16:00 2003 +0000
     5.3 @@ -0,0 +1,525 @@
     5.4 +#include <stdio.h>
     5.5 +#include <stdlib.h>
     5.6 +#include <string.h>
     5.7 +
     5.8 +#include "libpdf.h"
     5.9 +#include "libpdf_util.h"
    5.10 +#include "libpdf_prim.h"
    5.11 +#include "libpdf_private.h"
    5.12 +
    5.13 +
    5.14 +struct pdf_array_elem
    5.15 +{
    5.16 +  struct pdf_array_elem *next;
    5.17 +  struct pdf_obj        *val;
    5.18 +};
    5.19 +
    5.20 +
    5.21 +struct pdf_array
    5.22 +{
    5.23 +  struct pdf_array_elem *first;
    5.24 +  struct pdf_array_elem *last;
    5.25 +};
    5.26 +
    5.27 +
    5.28 +struct pdf_dict_entry
    5.29 +{
    5.30 +  struct pdf_dict_entry *next;
    5.31 +  char                  *key;
    5.32 +  struct pdf_obj        *val;
    5.33 +};
    5.34 +
    5.35 +
    5.36 +struct pdf_dict
    5.37 +{
    5.38 +  struct pdf_dict_entry *first;
    5.39 +};
    5.40 +
    5.41 +
    5.42 +struct pdf_stream
    5.43 +{
    5.44 +  struct pdf_obj *stream_dict;
    5.45 +  struct pdf_obj *length;
    5.46 +  pdf_stream_write_callback callback;
    5.47 +  void *app_data;  /* arg to pass to callback */
    5.48 +  struct pdf_obj *filters;  /* name or array of names */
    5.49 +  struct pdf_obj *decode_parms;
    5.50 +};
    5.51 +
    5.52 +
    5.53 +struct pdf_obj
    5.54 +{
    5.55 +  /* these fields only apply to indirectly referenced objects */
    5.56 +  struct pdf_obj      *prev;
    5.57 +  struct pdf_obj      *next;
    5.58 +  unsigned long       obj_num;
    5.59 +  unsigned long       obj_gen;
    5.60 +  long int            file_offset;
    5.61 +
    5.62 +  /* these fields apply to all objects */
    5.63 +  unsigned long       ref_count;
    5.64 +  pdf_obj_type        type;
    5.65 +  union {
    5.66 +    int               bool;
    5.67 +    char              *name;
    5.68 +    char              *string;
    5.69 +    unsigned long     integer;
    5.70 +    double            real;
    5.71 +    struct pdf_obj    *ind_ref;
    5.72 +    struct pdf_dict   dict;
    5.73 +    struct pdf_array  array;
    5.74 +    struct pdf_stream stream;
    5.75 +  } val;
    5.76 +};
    5.77 +
    5.78 +
    5.79 +struct pdf_obj *ref (struct pdf_obj *obj)
    5.80 +{
    5.81 +  obj->ref_count++;
    5.82 +  return (obj);
    5.83 +}
    5.84 +
    5.85 +
    5.86 +void unref (struct pdf_obj *obj)
    5.87 +{
    5.88 +  if ((--obj->ref_count) == 0)
    5.89 +    {
    5.90 +      /* $$$ free the object */
    5.91 +    }
    5.92 +}
    5.93 +
    5.94 +
    5.95 +struct pdf_obj *pdf_deref_ind_obj (struct pdf_obj *ind_obj)
    5.96 +{
    5.97 +  pdf_assert (ind_obj->type == PT_IND_REF);
    5.98 +  return (ind_obj->val.ind_ref);
    5.99 +}
   5.100 +
   5.101 +
   5.102 +void pdf_set_dict_entry (struct pdf_obj *dict_obj, char *key, struct pdf_obj *val)
   5.103 +{
   5.104 +  struct pdf_dict_entry *entry;
   5.105 +
   5.106 +  if (dict_obj->type == PT_IND_REF)
   5.107 +    dict_obj = pdf_deref_ind_obj (dict_obj);
   5.108 +
   5.109 +  pdf_assert (dict_obj->type == PT_DICTIONARY);
   5.110 +
   5.111 +  /* replacing existing entry? */
   5.112 +  for (entry = dict_obj->val.dict.first; entry; entry = entry->next)
   5.113 +    if (strcmp (entry->key, key) == 0)
   5.114 +      {
   5.115 +	unref (entry->val);
   5.116 +	entry->val = ref (val);
   5.117 +	return;
   5.118 +      }
   5.119 +
   5.120 +  /* new entry */
   5.121 +  entry = pdf_calloc (sizeof (struct pdf_dict_entry));
   5.122 +
   5.123 +  entry->next = dict_obj->val.dict.first;
   5.124 +  dict_obj->val.dict.first = entry;
   5.125 +
   5.126 +  entry->key = pdf_strdup (key);
   5.127 +  entry->val = ref (val);
   5.128 +}
   5.129 +
   5.130 +
   5.131 +struct pdf_obj *pdf_get_dict_entry (struct pdf_obj *dict_obj, char *key)
   5.132 +{
   5.133 +  struct pdf_dict_entry *entry;
   5.134 +
   5.135 +  if (dict_obj->type == PT_IND_REF)
   5.136 +    dict_obj = pdf_deref_ind_obj (dict_obj);
   5.137 +
   5.138 +  pdf_assert (dict_obj->type == PT_DICTIONARY);
   5.139 +
   5.140 +  for (entry = dict_obj->val.dict.first; entry; entry = entry->next)
   5.141 +    if (strcmp (entry->key, key) == 0)
   5.142 +      return (entry->val);
   5.143 +
   5.144 +  return (NULL);
   5.145 +}
   5.146 +
   5.147 +
   5.148 +void pdf_add_array_elem (struct pdf_obj *array_obj, struct pdf_obj *val)
   5.149 +{
   5.150 +  struct pdf_array_elem *elem = pdf_calloc (sizeof (struct pdf_array_elem));
   5.151 +
   5.152 +  if (array_obj->type == PT_IND_REF)
   5.153 +    array_obj = pdf_deref_ind_obj (array_obj);
   5.154 +
   5.155 +  pdf_assert (array_obj->type == PT_ARRAY);
   5.156 +
   5.157 +  elem->val = ref (val);
   5.158 +
   5.159 +  if (! array_obj->val.array.first)
   5.160 +    array_obj->val.array.first = elem;
   5.161 +  else
   5.162 +    array_obj->val.array.last->next = elem;
   5.163 +
   5.164 +  array_obj->val.array.last = elem;
   5.165 +}
   5.166 +
   5.167 +
   5.168 +struct pdf_obj *pdf_new_obj (pdf_obj_type type)
   5.169 +{
   5.170 +  struct pdf_obj *obj = pdf_calloc (sizeof (struct pdf_obj));
   5.171 +  obj->type = type;
   5.172 +  return (obj);
   5.173 +}
   5.174 +
   5.175 +
   5.176 +struct pdf_obj *pdf_new_bool (int bool)
   5.177 +{
   5.178 +  struct pdf_obj *obj = pdf_new_obj (PT_BOOL);
   5.179 +  obj->val.bool = bool;
   5.180 +  return (obj);
   5.181 +}
   5.182 +
   5.183 +
   5.184 +struct pdf_obj *pdf_new_name (char *name)
   5.185 +{
   5.186 +  struct pdf_obj *obj = pdf_new_obj (PT_NAME);
   5.187 +  obj->val.name = pdf_strdup (name);
   5.188 +  return (obj);
   5.189 +}
   5.190 +
   5.191 +
   5.192 +struct pdf_obj *pdf_new_string (char *str)
   5.193 +{
   5.194 +  struct pdf_obj *obj = pdf_new_obj (PT_STRING);
   5.195 +  obj->val.string = pdf_strdup (str);
   5.196 +  return (obj);
   5.197 +}
   5.198 +
   5.199 +
   5.200 +struct pdf_obj *pdf_new_integer (unsigned long val)
   5.201 +{
   5.202 +  struct pdf_obj *obj = pdf_new_obj (PT_INTEGER);
   5.203 +  obj->val.integer = val;
   5.204 +  return (obj);
   5.205 +}
   5.206 +
   5.207 +
   5.208 +struct pdf_obj *pdf_new_real (double val)
   5.209 +{
   5.210 +  struct pdf_obj *obj = pdf_new_obj (PT_REAL);
   5.211 +  obj->val.real = val;
   5.212 +  return (obj);
   5.213 +}
   5.214 +
   5.215 +
   5.216 +struct pdf_obj *pdf_new_stream (pdf_file_handle pdf_file,
   5.217 +				struct pdf_obj *stream_dict,
   5.218 +				pdf_stream_write_callback callback,
   5.219 +				void *app_data)
   5.220 +{
   5.221 +  struct pdf_obj *obj = pdf_new_obj (PT_STREAM);
   5.222 +
   5.223 +  obj->val.stream.stream_dict = stream_dict;
   5.224 +  obj->val.stream.length = pdf_new_ind_ref (pdf_file, pdf_new_integer (0));
   5.225 +  pdf_set_dict_entry (obj->val.stream.stream_dict, "Length", obj->val.stream.length);
   5.226 +
   5.227 +  obj->val.stream.callback = callback;
   5.228 +  obj->val.stream.app_data = app_data;
   5.229 +  return (obj);
   5.230 +}
   5.231 +
   5.232 +
   5.233 +/* $$$ currently limited to one filter per stream */
   5.234 +void pdf_stream_add_filter (struct pdf_obj *stream,
   5.235 +			    char *filter_name,
   5.236 +			    struct pdf_obj *decode_parms)
   5.237 +{
   5.238 +  if (stream->type == PT_IND_REF)
   5.239 +    stream = pdf_deref_ind_obj (stream);
   5.240 +
   5.241 +  pdf_assert (stream->type == PT_STREAM);
   5.242 +
   5.243 +  pdf_set_dict_entry (stream->val.stream.stream_dict, "Filter", pdf_new_name (filter_name));
   5.244 +  if (decode_parms)
   5.245 +    pdf_set_dict_entry (stream->val.stream.stream_dict, "DecodeParms", decode_parms);
   5.246 +}
   5.247 +
   5.248 +
   5.249 +struct pdf_obj *pdf_new_ind_ref (pdf_file_handle pdf_file, struct pdf_obj *obj)
   5.250 +{
   5.251 +  struct pdf_obj *ind_obj;
   5.252 +
   5.253 +  pdf_assert (obj->type != PT_IND_REF);
   5.254 +
   5.255 +  ind_obj = pdf_new_obj (PT_IND_REF);
   5.256 +
   5.257 +  ind_obj->type = PT_IND_REF;
   5.258 +  ind_obj->val.ind_ref = obj;
   5.259 +
   5.260 +  /* is there already an indirect reference to this object? */
   5.261 +  if (! obj->obj_num)
   5.262 +    {
   5.263 +      /* no, assign object number/generation and add to linked list */
   5.264 +      if (! pdf_file->first_ind_obj)
   5.265 +	{
   5.266 +	  obj->obj_num = 1;
   5.267 +	  pdf_file->first_ind_obj = pdf_file->last_ind_obj = obj;
   5.268 +	}
   5.269 +      else
   5.270 +	{
   5.271 +	  obj->obj_num = pdf_file->last_ind_obj->obj_num + 1;
   5.272 +	  pdf_file->last_ind_obj->next = obj;
   5.273 +	  obj->prev = pdf_file->last_ind_obj;
   5.274 +	  pdf_file->last_ind_obj = obj;
   5.275 +	}
   5.276 +    }
   5.277 +
   5.278 +  return (ind_obj);
   5.279 +}
   5.280 +
   5.281 +
   5.282 +unsigned long pdf_get_integer (struct pdf_obj *obj)
   5.283 +{
   5.284 +  if (obj->type == PT_IND_REF)
   5.285 +    obj = pdf_deref_ind_obj (obj);
   5.286 +
   5.287 +  pdf_assert (obj->type == PT_INTEGER);
   5.288 +
   5.289 +  return (obj->val.integer);
   5.290 +}
   5.291 +
   5.292 +void pdf_set_integer (struct pdf_obj *obj, unsigned long val)
   5.293 +{
   5.294 +  if (obj->type == PT_IND_REF)
   5.295 +    obj = pdf_deref_ind_obj (obj);
   5.296 +
   5.297 +  pdf_assert (obj->type == PT_INTEGER);
   5.298 +
   5.299 +  obj->val.integer = val;
   5.300 +}
   5.301 +
   5.302 +
   5.303 +double pdf_get_real (struct pdf_obj *obj)
   5.304 +{
   5.305 +  if (obj->type == PT_IND_REF)
   5.306 +    obj = pdf_deref_ind_obj (obj);
   5.307 +
   5.308 +  pdf_assert (obj->type == PT_REAL);
   5.309 +
   5.310 +  return (obj->val.real);
   5.311 +}
   5.312 +
   5.313 +void pdf_set_real (struct pdf_obj *obj, double val)
   5.314 +{
   5.315 +  if (obj->type == PT_IND_REF)
   5.316 +    obj = pdf_deref_ind_obj (obj);
   5.317 +
   5.318 +  pdf_assert (obj->type == PT_REAL);
   5.319 +
   5.320 +  obj->val.real = val;
   5.321 +}
   5.322 +
   5.323 +
   5.324 +static int name_char_needs_quoting (char c)
   5.325 +{
   5.326 +  return ((c < '!')  || (c > '~')  || (c == '/') || (c == '\\') ||
   5.327 +	  (c == '(') || (c == ')') || (c == '<') || (c == '>')  ||
   5.328 +	  (c == '[') || (c == ']') || (c == '{') || (c == '}')  ||
   5.329 +	  (c == '%'));
   5.330 +}
   5.331 +
   5.332 +
   5.333 +void pdf_write_name (pdf_file_handle pdf_file, char *s)
   5.334 +{
   5.335 +  fprintf (pdf_file->f, "/");
   5.336 +  while (*s)
   5.337 +    if (name_char_needs_quoting (*s))
   5.338 +      fprintf (pdf_file->f, "#%02x", 0xff & *(s++));
   5.339 +    else
   5.340 +      fprintf (pdf_file->f, "%c", *(s++));
   5.341 +  fprintf (pdf_file->f, " ");
   5.342 +}
   5.343 +
   5.344 +
   5.345 +static int string_char_needs_quoting (char c)
   5.346 +{
   5.347 +  return ((c < ' ')  || (c > '~')  || (c == '\\') ||
   5.348 +	  (c == '(') || (c == ')'));
   5.349 +}
   5.350 +
   5.351 +
   5.352 +void pdf_write_string (pdf_file_handle pdf_file, char *s)
   5.353 +{
   5.354 +  fprintf (pdf_file->f, "(");
   5.355 +  while (*s)
   5.356 +    if (string_char_needs_quoting (*s))
   5.357 +      fprintf (pdf_file->f, "\\%03o", 0xff & *(s++));
   5.358 +    else
   5.359 +      fprintf (pdf_file->f, "%c", *(s++));
   5.360 +  fprintf (pdf_file->f, ") ");
   5.361 +}
   5.362 +
   5.363 +
   5.364 +void pdf_write_real (pdf_file_handle pdf_file, double num)
   5.365 +{
   5.366 +  /* $$$ not actually good enough, precision needs to be variable,
   5.367 +     and no exponent is allowed */
   5.368 +  fprintf (pdf_file->f, "%0f ", num);
   5.369 +}
   5.370 +
   5.371 +
   5.372 +void pdf_write_ind_ref (pdf_file_handle pdf_file, struct pdf_obj *ind_obj)
   5.373 +{
   5.374 +  struct pdf_obj *obj = pdf_deref_ind_obj (ind_obj);
   5.375 +  fprintf (pdf_file->f, "%ld %ld R ", obj->obj_num, obj->obj_gen);
   5.376 +}
   5.377 +
   5.378 +
   5.379 +void pdf_write_array (pdf_file_handle pdf_file, struct pdf_obj *array_obj)
   5.380 +{
   5.381 +  struct pdf_array_elem *elem;
   5.382 +
   5.383 +  pdf_assert (array_obj->type == PT_ARRAY);
   5.384 +
   5.385 +  fprintf (pdf_file->f, "[ ");
   5.386 +  for (elem = array_obj->val.array.first; elem; elem = elem->next)
   5.387 +    {
   5.388 +      pdf_write_obj (pdf_file, elem->val);
   5.389 +      fprintf (pdf_file->f, " ");
   5.390 +    }
   5.391 +  fprintf (pdf_file->f, "] ");
   5.392 +}
   5.393 +
   5.394 +
   5.395 +void pdf_write_dict (pdf_file_handle pdf_file, struct pdf_obj *dict_obj)
   5.396 +{
   5.397 +  struct pdf_dict_entry *entry;
   5.398 +
   5.399 +  pdf_assert (dict_obj->type == PT_DICTIONARY);
   5.400 +
   5.401 +  fprintf (pdf_file->f, "<<\r\n");
   5.402 +  for (entry = dict_obj->val.dict.first; entry; entry = entry->next)
   5.403 +    {
   5.404 +      pdf_write_name (pdf_file, entry->key);
   5.405 +      fprintf (pdf_file->f, " ");
   5.406 +      pdf_write_obj (pdf_file, entry->val);
   5.407 +      fprintf (pdf_file->f, "\r\n");
   5.408 +    }
   5.409 +  fprintf (pdf_file->f, ">>\r\n");
   5.410 +}
   5.411 +
   5.412 +
   5.413 +void pdf_stream_write_data (pdf_file_handle pdf_file,
   5.414 +			    struct pdf_obj *stream,
   5.415 +			    char *data,
   5.416 +			    unsigned long len)
   5.417 +{
   5.418 +  while (len)
   5.419 +    {
   5.420 +      unsigned long l2 = fwrite (data, 1, len, pdf_file->f);
   5.421 +      data += l2;
   5.422 +      len -= l2;
   5.423 +      if (ferror (pdf_file->f))
   5.424 +	pdf_fatal ("error writing stream data\n");
   5.425 +    }
   5.426 +}
   5.427 +
   5.428 +
   5.429 +void pdf_write_stream (pdf_file_handle pdf_file, struct pdf_obj *stream)
   5.430 +{
   5.431 +  unsigned long begin_pos, end_pos;
   5.432 +
   5.433 +  pdf_assert (stream->type == PT_STREAM);
   5.434 +
   5.435 +  pdf_write_dict (pdf_file, stream->val.stream.stream_dict);
   5.436 +  fprintf (pdf_file->f, "stream\r\n");
   5.437 +  begin_pos = ftell (pdf_file->f);
   5.438 +  stream->val.stream.callback (pdf_file,
   5.439 +			       stream,
   5.440 +			       stream->val.stream.app_data);
   5.441 +  end_pos = ftell (pdf_file->f);
   5.442 +  fprintf (pdf_file->f, "\r\nendstream\r\n");
   5.443 +
   5.444 +  pdf_set_integer (stream->val.stream.length, end_pos - begin_pos);
   5.445 +}
   5.446 +
   5.447 +
   5.448 +void pdf_write_obj (pdf_file_handle pdf_file, struct pdf_obj *obj)
   5.449 +{
   5.450 +  switch (obj->type)
   5.451 +    {
   5.452 +    case PT_NULL:
   5.453 +      fprintf (pdf_file->f, "null ");
   5.454 +      break;
   5.455 +    case PT_BOOL:
   5.456 +      if (obj->val.bool)
   5.457 +	fprintf (pdf_file->f, "true ");
   5.458 +      else
   5.459 +	fprintf (pdf_file->f, "false ");
   5.460 +      break;
   5.461 +    case PT_NAME:
   5.462 +      pdf_write_name (pdf_file, obj->val.name);
   5.463 +      break;
   5.464 +    case PT_STRING:
   5.465 +      pdf_write_string (pdf_file, obj->val.string);
   5.466 +      break;
   5.467 +    case PT_INTEGER:
   5.468 +      fprintf (pdf_file->f, "%ld ", obj->val.integer);
   5.469 +      break;
   5.470 +    case PT_REAL:
   5.471 +      pdf_write_real (pdf_file, obj->val.real);
   5.472 +      break;
   5.473 +    case PT_IND_REF:
   5.474 +      pdf_write_ind_ref (pdf_file, obj);
   5.475 +      break;
   5.476 +    case PT_DICTIONARY:
   5.477 +      pdf_write_dict (pdf_file, obj);
   5.478 +      break;
   5.479 +    case PT_ARRAY:
   5.480 +      pdf_write_array (pdf_file, obj);
   5.481 +      break;
   5.482 +    case PT_STREAM:
   5.483 +      pdf_write_stream (pdf_file, obj);
   5.484 +      break;
   5.485 +    default:
   5.486 +      pdf_fatal ("bad object type\n");
   5.487 +    }
   5.488 +}
   5.489 +
   5.490 +
   5.491 +void pdf_write_ind_obj (pdf_file_handle pdf_file, struct pdf_obj *ind_obj)
   5.492 +{
   5.493 +  struct pdf_obj *obj;
   5.494 +
   5.495 +  if (ind_obj->type == PT_IND_REF)
   5.496 +    obj = pdf_deref_ind_obj (ind_obj);
   5.497 +  else
   5.498 +    obj = ind_obj;
   5.499 +
   5.500 +  obj->file_offset = ftell (pdf_file->f);
   5.501 +  fprintf (pdf_file->f, "%ld %ld obj\r\n", obj->obj_num, obj->obj_gen);
   5.502 +  pdf_write_obj (pdf_file, obj);
   5.503 +  fprintf (pdf_file->f, "endobj\r\n");
   5.504 +}
   5.505 +
   5.506 +
   5.507 +void pdf_write_all_ind_obj (pdf_file_handle pdf_file)
   5.508 +{
   5.509 +  struct pdf_obj *ind_obj;
   5.510 +  for (ind_obj = pdf_file->first_ind_obj; ind_obj; ind_obj = ind_obj->next)
   5.511 +    if (! ind_obj->file_offset)
   5.512 +      pdf_write_ind_obj (pdf_file, ind_obj);
   5.513 +}
   5.514 +
   5.515 +
   5.516 +unsigned long pdf_write_xref (pdf_file_handle pdf_file)
   5.517 +{
   5.518 +  struct pdf_obj *ind_obj;
   5.519 +  pdf_file->xref_offset = ftell (pdf_file->f);
   5.520 +  fprintf (pdf_file->f, "xref\r\n");
   5.521 +  fprintf (pdf_file->f, "0 %ld\r\n", pdf_file->last_ind_obj->obj_num + 1);
   5.522 +  fprintf (pdf_file->f, "0000000000 65535 f\r\n");
   5.523 +  for (ind_obj = pdf_file->first_ind_obj; ind_obj; ind_obj = ind_obj->next)
   5.524 +    fprintf (pdf_file->f, "%010ld 00000 n\r\n", ind_obj->file_offset);
   5.525 +  return (pdf_file->last_ind_obj->obj_num + 1);
   5.526 +}
   5.527 +
   5.528 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/pdf_prim.h	Thu Feb 20 12:16:00 2003 +0000
     6.3 @@ -0,0 +1,100 @@
     6.4 +typedef enum
     6.5 +{
     6.6 +  PT_BAD,
     6.7 +
     6.8 +  /* scalar */
     6.9 +  PT_NULL,
    6.10 +  PT_BOOL,
    6.11 +  PT_NAME,
    6.12 +  PT_STRING,
    6.13 +  PT_INTEGER,
    6.14 +  PT_REAL,
    6.15 +  PT_IND_REF,
    6.16 +
    6.17 +  /* composite */
    6.18 +  PT_DICTIONARY,
    6.19 +  PT_ARRAY,
    6.20 +  PT_STREAM
    6.21 +} pdf_obj_type;
    6.22 +
    6.23 +
    6.24 +struct pdf_obj;
    6.25 +
    6.26 +
    6.27 +typedef void (*pdf_stream_write_callback)(pdf_file_handle pdf_file,
    6.28 +					  struct pdf_obj *stream,
    6.29 +					  void *app_data);
    6.30 +
    6.31 +
    6.32 +void pdf_set_dict_entry (struct pdf_obj *dict_obj, char *key, struct pdf_obj *val);
    6.33 +struct pdf_obj *pdf_get_dict_entry (struct pdf_obj *dict_obj, char *key);
    6.34 +
    6.35 +
    6.36 +void pdf_add_array_elem (struct pdf_obj *array_obj, struct pdf_obj *val);
    6.37 +
    6.38 +
    6.39 +/* Create a new object that will NOT be used indirectly */
    6.40 +struct pdf_obj *pdf_new_obj (pdf_obj_type type);
    6.41 +
    6.42 +struct pdf_obj *pdf_new_bool (int bool);
    6.43 +
    6.44 +struct pdf_obj *pdf_new_name (char *name);
    6.45 +
    6.46 +struct pdf_obj *pdf_new_string (char *str);
    6.47 +
    6.48 +struct pdf_obj *pdf_new_integer (unsigned long val);
    6.49 +
    6.50 +struct pdf_obj *pdf_new_real (double val);
    6.51 +
    6.52 +
    6.53 +/* Create a new indirect object */
    6.54 +struct pdf_obj *pdf_new_ind_ref (pdf_file_handle pdf_file, struct pdf_obj *obj);
    6.55 +
    6.56 +/* get the object referenced by an indirect reference */
    6.57 +struct pdf_obj *pdf_deref_ind_obj (struct pdf_obj *ind_obj);
    6.58 +
    6.59 +
    6.60 +unsigned long pdf_get_integer (struct pdf_obj *obj);
    6.61 +void pdf_set_integer (struct pdf_obj *obj, unsigned long val);
    6.62 +
    6.63 +
    6.64 +double pdf_get_real (struct pdf_obj *obj);
    6.65 +void pdf_set_real (struct pdf_obj *obj, double val);
    6.66 +
    6.67 +
    6.68 +/* The callback will be called when the stream data is to be written to the
    6.69 +   file.  app_data will be passed as an argument to the callback. */
    6.70 +struct pdf_obj *pdf_new_stream (pdf_file_handle pdf_file,
    6.71 +				struct pdf_obj *stream_dict,
    6.72 +				pdf_stream_write_callback callback,
    6.73 +				void *app_data);
    6.74 +
    6.75 +/* The callback should call pdf_stream_write_data to write the actual
    6.76 +   stream data. */
    6.77 +void pdf_stream_write_data (pdf_file_handle pdf_file,
    6.78 +			    struct pdf_obj *stream,
    6.79 +			    char *data,
    6.80 +			    unsigned long len);
    6.81 +
    6.82 +void pdf_stream_add_filter (struct pdf_obj *stream,
    6.83 +			    char *filter_name,
    6.84 +			    struct pdf_obj *decode_parms);
    6.85 +
    6.86 +
    6.87 +/* Write the object to the file */
    6.88 +void pdf_write_obj (pdf_file_handle pdf_file, struct pdf_obj *obj);
    6.89 +
    6.90 +
    6.91 +/* Write the indirect object to the file.  For most objects this should
    6.92 +   be done by pdf_write_all_ind_obj() when the file is being closed, but for
    6.93 +   large objects such as streams, it's probably better to do it as soon as the
    6.94 +   object is complete. */
    6.95 +void pdf_write_ind_obj (pdf_file_handle pdf_file, struct pdf_obj *ind_obj);
    6.96 +
    6.97 +
    6.98 +/* Write all indirect objects that haven't already been written to the file. */
    6.99 +void pdf_write_all_ind_obj (pdf_file_handle pdf_file);
   6.100 +
   6.101 +
   6.102 +/* Write the cross reference table, and return the maximum object number */
   6.103 +unsigned long pdf_write_xref (pdf_file_handle pdf_file);
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/pdf_private.h	Thu Feb 20 12:16:00 2003 +0000
     7.3 @@ -0,0 +1,32 @@
     7.4 +struct pdf_page
     7.5 +{
     7.6 +  pdf_file_handle pdf_file;
     7.7 +  struct pdf_obj *page_dict;
     7.8 +  struct pdf_obj *media_box;
     7.9 +  struct pdf_obj *procset;
    7.10 +  struct pdf_obj *resources;
    7.11 +
    7.12 +  char last_XObject_name;
    7.13 +  struct pdf_obj *XObject_dict;
    7.14 +};
    7.15 +
    7.16 +
    7.17 +struct pdf_pages
    7.18 +{
    7.19 +  struct pdf_obj *pages_dict;
    7.20 +  struct pdf_obj *kids;
    7.21 +  struct pdf_obj *count;
    7.22 +};
    7.23 +
    7.24 +
    7.25 +struct pdf_file
    7.26 +{
    7.27 +  FILE             *f;
    7.28 +  struct pdf_obj   *first_ind_obj;
    7.29 +  struct pdf_obj   *last_ind_obj;
    7.30 +  long int         xref_offset;
    7.31 +  struct pdf_obj   *catalog;
    7.32 +  struct pdf_obj   *info;
    7.33 +  struct pdf_pages *root;
    7.34 +  struct pdf_obj   *trailer_dict;
    7.35 +};
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/pdf_util.c	Thu Feb 20 12:16:00 2003 +0000
     8.3 @@ -0,0 +1,37 @@
     8.4 +#include <stdarg.h>
     8.5 +#include <stdio.h>
     8.6 +#include <stdlib.h>
     8.7 +#include <string.h>
     8.8 +
     8.9 +#include "libpdf.h"
    8.10 +#include "libpdf_util.h"
    8.11 +
    8.12 +
    8.13 +void pdf_fatal (char *fmt, ...)
    8.14 +{
    8.15 +  va_list ap;
    8.16 +
    8.17 +  va_start (ap, fmt);
    8.18 +  vfprintf (stderr, fmt, ap);
    8.19 +  va_end (ap);
    8.20 +
    8.21 +  exit (2);
    8.22 +}
    8.23 +
    8.24 +
    8.25 +void *pdf_calloc (long int size)
    8.26 +{
    8.27 +  void *m = calloc (1, size);
    8.28 +  if (! m)
    8.29 +    pdf_fatal ("failed to allocate memory\n");
    8.30 +  return (m);
    8.31 +}
    8.32 +
    8.33 +
    8.34 +char *pdf_strdup (char *s)
    8.35 +{
    8.36 +  unsigned long len = strlen (s);
    8.37 +  char *s2 = pdf_calloc (len + 1);
    8.38 +  strcpy (s2, s);
    8.39 +  return (s2);
    8.40 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/pdf_util.h	Thu Feb 20 12:16:00 2003 +0000
     9.3 @@ -0,0 +1,11 @@
     9.4 +void pdf_fatal (char *fmt, ...);
     9.5 +
     9.6 +void *pdf_calloc (long int size);
     9.7 +
     9.8 +char *pdf_strdup (char *s);
     9.9 +
    9.10 +#define pdf_assert(cond) do \
    9.11 +    { \
    9.12 +      if (! (cond)) \
    9.13 +        pdf_fatal ("assert at %s(%d)\n", __FILE__, __LINE__); \
    9.14 +    } while (0)