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