Thu, 20 Feb 2003 12:16:00 +0000
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)