my own PDF routines to replace Panda.
This commit is contained in:
179
bitblt_g4.c
Normal file
179
bitblt_g4.c
Normal file
@@ -0,0 +1,179 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "libpdf.h"
|
||||
#include "libpdf_util.h"
|
||||
#include "libpdf_prim.h"
|
||||
#include "libpdf_private.h"
|
||||
|
||||
|
||||
struct pdf_g4_image
|
||||
{
|
||||
unsigned long Columns;
|
||||
unsigned long Rows;
|
||||
unsigned long rowbytes;
|
||||
int BlackIs1;
|
||||
unsigned char *data;
|
||||
unsigned long len;
|
||||
char XObject_name [4];
|
||||
};
|
||||
|
||||
|
||||
char pdf_new_XObject (pdf_page_handle pdf_page, struct pdf_obj *ind_ref)
|
||||
{
|
||||
char XObject_name [4] = "Im ";
|
||||
|
||||
XObject_name [2] = ++pdf_page->last_XObject_name;
|
||||
|
||||
if (! pdf_page->XObject_dict)
|
||||
{
|
||||
pdf_page->XObject_dict = pdf_new_obj (PT_DICTIONARY);
|
||||
pdf_set_dict_entry (pdf_page->resources, "XObject", pdf_page->XObject_dict);
|
||||
}
|
||||
|
||||
pdf_set_dict_entry (pdf_page->XObject_dict, & XObject_name [0], ind_ref);
|
||||
|
||||
return (pdf_page->last_XObject_name);
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_g4_content_callback (pdf_file_handle pdf_file,
|
||||
struct pdf_obj *stream,
|
||||
void *app_data)
|
||||
{
|
||||
unsigned long width = (8.5 * 72); /* full width of page */
|
||||
unsigned long height = (11 * 72); /* full height of page */
|
||||
unsigned long x = 0; /* 0 is left edge */
|
||||
unsigned long y = 0; /* 0 is bottom edge */
|
||||
struct pdf_g4_image *image = app_data;
|
||||
|
||||
char str1 [100];
|
||||
char *str2 = "/";
|
||||
char *str3 = " Do\r\n";
|
||||
|
||||
/* width 0 0 height x y cm */
|
||||
sprintf (str1, "q %ld 0 0 %ld %ld %ld cm\r\n", width, height, x, y);
|
||||
|
||||
pdf_stream_write_data (pdf_file, stream, str1, strlen (str1));
|
||||
pdf_stream_write_data (pdf_file, stream, str2, strlen (str2));
|
||||
pdf_stream_write_data (pdf_file, stream, & image->XObject_name [0],
|
||||
strlen (& image->XObject_name [0]));
|
||||
pdf_stream_write_data (pdf_file, stream, str3, strlen (str3));
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_g4_fax_image_callback (pdf_file_handle pdf_file,
|
||||
struct pdf_obj *stream,
|
||||
void *app_data)
|
||||
{
|
||||
struct pdf_g4_image *image = app_data;
|
||||
|
||||
#if 1
|
||||
pdf_stream_write_data (pdf_file, stream, image->data, image->len);
|
||||
#else
|
||||
unsigned long row = 0;
|
||||
unsigned char *ref;
|
||||
unsigned char *raw;
|
||||
|
||||
ref = NULL;
|
||||
raw = image->data;
|
||||
|
||||
while (row < image->Rows)
|
||||
{
|
||||
pdf_stream_write_data (pdf_file, stream, raw, image->rowbytes);
|
||||
|
||||
row++;
|
||||
ref = raw;
|
||||
raw += image->rowbytes;
|
||||
}
|
||||
/* $$$ generate and write EOFB code */
|
||||
/* $$$ flush any remaining buffered bits */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
|
||||
unsigned long Columns,
|
||||
unsigned long Rows,
|
||||
unsigned long rowbytes,
|
||||
int ImageMask,
|
||||
int BlackIs1, /* boolean, typ. false */
|
||||
unsigned char *data,
|
||||
unsigned long len)
|
||||
{
|
||||
struct pdf_g4_image *image;
|
||||
|
||||
struct pdf_obj *stream;
|
||||
struct pdf_obj *stream_dict;
|
||||
struct pdf_obj *decode_parms;
|
||||
|
||||
struct pdf_obj *content_stream;
|
||||
|
||||
image = pdf_calloc (sizeof (struct pdf_g4_image));
|
||||
|
||||
image->Columns = Columns;
|
||||
image->Rows = Rows;
|
||||
image->rowbytes = rowbytes;
|
||||
image->BlackIs1 = BlackIs1;
|
||||
image->data = data;
|
||||
image->len = len;
|
||||
|
||||
stream_dict = pdf_new_obj (PT_DICTIONARY);
|
||||
|
||||
stream = pdf_new_ind_ref (pdf_page->pdf_file,
|
||||
pdf_new_stream (pdf_page->pdf_file,
|
||||
stream_dict,
|
||||
& pdf_write_g4_fax_image_callback,
|
||||
image));
|
||||
|
||||
strcpy (& image->XObject_name [0], "Im ");
|
||||
image->XObject_name [2] = pdf_new_XObject (pdf_page, stream);
|
||||
|
||||
pdf_set_dict_entry (stream_dict, "Type", pdf_new_name ("XObject"));
|
||||
pdf_set_dict_entry (stream_dict, "Subtype", pdf_new_name ("Image"));
|
||||
pdf_set_dict_entry (stream_dict, "Name", pdf_new_name (& image->XObject_name [0]));
|
||||
pdf_set_dict_entry (stream_dict, "Width", pdf_new_integer (Columns));
|
||||
pdf_set_dict_entry (stream_dict, "Height", pdf_new_integer (Rows));
|
||||
pdf_set_dict_entry (stream_dict, "BitsPerComponent", pdf_new_integer (1));
|
||||
if (ImageMask)
|
||||
pdf_set_dict_entry (stream_dict, "ImageMask", pdf_new_bool (ImageMask));
|
||||
else
|
||||
pdf_set_dict_entry (stream_dict, "ColorSpace", pdf_new_name ("DeviceGray"));
|
||||
|
||||
decode_parms = pdf_new_obj (PT_DICTIONARY);
|
||||
|
||||
pdf_set_dict_entry (decode_parms,
|
||||
"K",
|
||||
pdf_new_integer (-1));
|
||||
|
||||
pdf_set_dict_entry (decode_parms,
|
||||
"Columns",
|
||||
pdf_new_integer (Columns));
|
||||
|
||||
pdf_set_dict_entry (decode_parms,
|
||||
"Rows",
|
||||
pdf_new_integer (Rows));
|
||||
|
||||
if (BlackIs1)
|
||||
pdf_set_dict_entry (decode_parms,
|
||||
"BlackIs1",
|
||||
pdf_new_bool (BlackIs1));
|
||||
|
||||
pdf_stream_add_filter (stream, "CCITTFaxDecode", decode_parms);
|
||||
|
||||
/* the following will write the stream, using our callback function to
|
||||
get the actual data */
|
||||
pdf_write_ind_obj (pdf_page->pdf_file, stream);
|
||||
|
||||
content_stream = pdf_new_ind_ref (pdf_page->pdf_file,
|
||||
pdf_new_stream (pdf_page->pdf_file,
|
||||
pdf_new_obj (PT_DICTIONARY),
|
||||
& pdf_write_g4_content_callback,
|
||||
image));
|
||||
|
||||
pdf_set_dict_entry (pdf_page->page_dict, "Contents", content_stream);
|
||||
|
||||
pdf_write_ind_obj (pdf_page->pdf_file, content_stream);
|
||||
}
|
||||
|
||||
171
pdf.c
Normal file
171
pdf.c
Normal file
@@ -0,0 +1,171 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#include "libpdf.h"
|
||||
#include "libpdf_util.h"
|
||||
#include "libpdf_prim.h"
|
||||
#include "libpdf_private.h"
|
||||
|
||||
|
||||
static void pdf_set_info (pdf_file_handle pdf_file, char *key, char *val)
|
||||
{
|
||||
if (! pdf_file->info)
|
||||
pdf_file->info = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
|
||||
|
||||
pdf_set_dict_entry (pdf_file->info, key, pdf_new_string (val));
|
||||
}
|
||||
|
||||
|
||||
void pdf_init (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
struct pdf_pages *pdf_new_pages (pdf_file_handle pdf_file)
|
||||
{
|
||||
struct pdf_pages *pages = pdf_calloc (sizeof (struct pdf_pages));
|
||||
pages->kids = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_ARRAY));
|
||||
pages->count = pdf_new_integer (0);
|
||||
pages->pages_dict = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
|
||||
pdf_set_dict_entry (pages->pages_dict, "Type", pdf_new_name ("Pages"));
|
||||
pdf_set_dict_entry (pages->pages_dict, "Kids", pages->kids);
|
||||
pdf_set_dict_entry (pages->pages_dict, "Count", pages->count);
|
||||
return (pages);
|
||||
}
|
||||
|
||||
|
||||
pdf_file_handle pdf_create (char *filename)
|
||||
{
|
||||
pdf_file_handle pdf_file;
|
||||
|
||||
pdf_file = pdf_calloc (sizeof (struct pdf_file));
|
||||
|
||||
pdf_file->f = fopen (filename, "wb");
|
||||
if (! pdf_file->f)
|
||||
{
|
||||
pdf_fatal ("error opening output file\n");
|
||||
}
|
||||
|
||||
pdf_file->root = pdf_new_pages (pdf_file);
|
||||
|
||||
pdf_file->catalog = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
|
||||
pdf_set_dict_entry (pdf_file->catalog, "Type", pdf_new_name ("Catalog"));
|
||||
pdf_set_dict_entry (pdf_file->catalog, "Pages", pdf_file->root->pages_dict);
|
||||
/* Outlines dictionary will be created later if needed*/
|
||||
pdf_set_dict_entry (pdf_file->catalog, "PageMode", pdf_new_name ("UseNone"));
|
||||
|
||||
pdf_file->info = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
|
||||
pdf_set_info (pdf_file, "Producer", "libpdf, Copyright 2003 Eric Smith <eric@brouhaha.com>");
|
||||
|
||||
pdf_file->trailer_dict = pdf_new_obj (PT_DICTIONARY);
|
||||
/* Size key will be added later */
|
||||
pdf_set_dict_entry (pdf_file->trailer_dict, "Root", pdf_file->catalog);
|
||||
pdf_set_dict_entry (pdf_file->trailer_dict, "Info", pdf_file->info);
|
||||
|
||||
/* write file header */
|
||||
fprintf (pdf_file->f, "%%PDF-1.2\r\n");
|
||||
|
||||
return (pdf_file);
|
||||
}
|
||||
|
||||
|
||||
void pdf_close (pdf_file_handle pdf_file)
|
||||
{
|
||||
/* write body */
|
||||
pdf_write_all_ind_obj (pdf_file);
|
||||
|
||||
/* write cross reference table and get maximum object number */
|
||||
pdf_set_dict_entry (pdf_file->trailer_dict, "Size", pdf_new_integer (pdf_write_xref (pdf_file)));
|
||||
|
||||
/* write trailer */
|
||||
fprintf (pdf_file->f, "trailer\r\n");
|
||||
pdf_write_obj (pdf_file, pdf_file->trailer_dict);
|
||||
fprintf (pdf_file->f, "startxref\r\n");
|
||||
fprintf (pdf_file->f, "%ld\r\n", pdf_file->xref_offset);
|
||||
fprintf (pdf_file->f, "%%%%EOF\r\n");
|
||||
|
||||
fclose (pdf_file->f);
|
||||
/* should free stuff here */
|
||||
}
|
||||
|
||||
|
||||
void pdf_set_author (pdf_file_handle pdf_file, char *author)
|
||||
{
|
||||
pdf_set_info (pdf_file, "Author", author);
|
||||
}
|
||||
|
||||
void pdf_set_creator (pdf_file_handle pdf_file, char *creator)
|
||||
{
|
||||
pdf_set_info (pdf_file, "Creator", creator);
|
||||
}
|
||||
|
||||
void pdf_set_producer (pdf_file_handle pdf_file, char *producer)
|
||||
{
|
||||
pdf_set_info (pdf_file, "Producer", producer);
|
||||
}
|
||||
|
||||
void pdf_set_title (pdf_file_handle pdf_file, char *title)
|
||||
{
|
||||
pdf_set_info (pdf_file, "Title", title);
|
||||
}
|
||||
|
||||
void pdf_set_subject (pdf_file_handle pdf_file, char *subject)
|
||||
{
|
||||
pdf_set_info (pdf_file, "Subject", subject);
|
||||
}
|
||||
|
||||
void pdf_set_keywords (pdf_file_handle pdf_file, char *keywords)
|
||||
{
|
||||
pdf_set_info (pdf_file, "Keywords", keywords);
|
||||
}
|
||||
|
||||
|
||||
pdf_page_handle pdf_new_page (pdf_file_handle pdf_file,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
pdf_page_handle page = pdf_calloc (sizeof (struct pdf_page));
|
||||
|
||||
page->pdf_file = pdf_file;
|
||||
|
||||
page->media_box = pdf_new_obj (PT_ARRAY);
|
||||
pdf_add_array_elem (page->media_box, pdf_new_real (0));
|
||||
pdf_add_array_elem (page->media_box, pdf_new_real (0));
|
||||
pdf_add_array_elem (page->media_box, pdf_new_real (width));
|
||||
pdf_add_array_elem (page->media_box, pdf_new_real (height));
|
||||
|
||||
page->procset = pdf_new_obj (PT_ARRAY);
|
||||
pdf_add_array_elem (page->procset, pdf_new_name ("PDF"));
|
||||
|
||||
page->resources = pdf_new_obj (PT_DICTIONARY);
|
||||
pdf_set_dict_entry (page->resources, "ProcSet", page->procset);
|
||||
|
||||
page->page_dict = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
|
||||
pdf_set_dict_entry (page->page_dict, "Type", pdf_new_name ("Page"));
|
||||
pdf_set_dict_entry (page->page_dict, "MediaBox", page->media_box);
|
||||
pdf_set_dict_entry (page->page_dict, "Resources", page->resources);
|
||||
|
||||
/* $$$ currently only support a single-level pages tree */
|
||||
pdf_set_dict_entry (page->page_dict, "Parent", pdf_file->root->pages_dict);
|
||||
pdf_add_array_elem (pdf_file->root->kids, page->page_dict);
|
||||
pdf_set_integer (pdf_file->root->count,
|
||||
pdf_get_integer (pdf_file->root->count) + 1);
|
||||
|
||||
page->last_XObject_name = '@'; /* first name will be "ImA" */
|
||||
|
||||
return (page);
|
||||
}
|
||||
|
||||
void pdf_close_page (pdf_page_handle pdf_page)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void pdf_set_page_number (pdf_page_handle pdf_page, char *page_number)
|
||||
{
|
||||
}
|
||||
|
||||
void pdf_bookmark (pdf_page_handle pdf_page, int level, char *name)
|
||||
{
|
||||
}
|
||||
44
pdf.h
Normal file
44
pdf.h
Normal file
@@ -0,0 +1,44 @@
|
||||
typedef struct pdf_file *pdf_file_handle;
|
||||
|
||||
typedef struct pdf_page *pdf_page_handle;
|
||||
|
||||
|
||||
void pdf_init (void);
|
||||
|
||||
pdf_file_handle pdf_create (char *filename);
|
||||
|
||||
void pdf_close (pdf_file_handle pdf_file);
|
||||
|
||||
void pdf_set_author (pdf_file_handle pdf_file, char *author);
|
||||
void pdf_set_creator (pdf_file_handle pdf_file, char *author);
|
||||
void pdf_set_title (pdf_file_handle pdf_file, char *author);
|
||||
void pdf_set_subject (pdf_file_handle pdf_file, char *author);
|
||||
void pdf_set_keywords (pdf_file_handle pdf_file, char *author);
|
||||
|
||||
|
||||
/* width and height in units of 1/72 inch */
|
||||
pdf_page_handle pdf_new_page (pdf_file_handle pdf_file,
|
||||
double width,
|
||||
double height);
|
||||
|
||||
void pdf_close_page (pdf_page_handle pdf_page);
|
||||
|
||||
|
||||
/* The length of the data must be Rows * rowbytes.
|
||||
Note that rowbytes must be at least (Columns+7)/8, but may be arbitrarily
|
||||
large. */
|
||||
void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
|
||||
unsigned long Columns,
|
||||
unsigned long Rows,
|
||||
unsigned long rowbytes,
|
||||
int ImageMask,
|
||||
int BlackIs1, /* boolean, typ. false */
|
||||
unsigned char *data,
|
||||
unsigned long len);
|
||||
|
||||
|
||||
void pdf_set_page_number (pdf_page_handle pdf_page, char *page_number);
|
||||
|
||||
void pdf_bookmark (pdf_page_handle pdf_page, int level, char *name);
|
||||
|
||||
void pdf_insert_tiff_image (pdf_page_handle pdf_page, char *filename);
|
||||
179
pdf_g4.c
Normal file
179
pdf_g4.c
Normal file
@@ -0,0 +1,179 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "libpdf.h"
|
||||
#include "libpdf_util.h"
|
||||
#include "libpdf_prim.h"
|
||||
#include "libpdf_private.h"
|
||||
|
||||
|
||||
struct pdf_g4_image
|
||||
{
|
||||
unsigned long Columns;
|
||||
unsigned long Rows;
|
||||
unsigned long rowbytes;
|
||||
int BlackIs1;
|
||||
unsigned char *data;
|
||||
unsigned long len;
|
||||
char XObject_name [4];
|
||||
};
|
||||
|
||||
|
||||
char pdf_new_XObject (pdf_page_handle pdf_page, struct pdf_obj *ind_ref)
|
||||
{
|
||||
char XObject_name [4] = "Im ";
|
||||
|
||||
XObject_name [2] = ++pdf_page->last_XObject_name;
|
||||
|
||||
if (! pdf_page->XObject_dict)
|
||||
{
|
||||
pdf_page->XObject_dict = pdf_new_obj (PT_DICTIONARY);
|
||||
pdf_set_dict_entry (pdf_page->resources, "XObject", pdf_page->XObject_dict);
|
||||
}
|
||||
|
||||
pdf_set_dict_entry (pdf_page->XObject_dict, & XObject_name [0], ind_ref);
|
||||
|
||||
return (pdf_page->last_XObject_name);
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_g4_content_callback (pdf_file_handle pdf_file,
|
||||
struct pdf_obj *stream,
|
||||
void *app_data)
|
||||
{
|
||||
unsigned long width = (8.5 * 72); /* full width of page */
|
||||
unsigned long height = (11 * 72); /* full height of page */
|
||||
unsigned long x = 0; /* 0 is left edge */
|
||||
unsigned long y = 0; /* 0 is bottom edge */
|
||||
struct pdf_g4_image *image = app_data;
|
||||
|
||||
char str1 [100];
|
||||
char *str2 = "/";
|
||||
char *str3 = " Do\r\n";
|
||||
|
||||
/* width 0 0 height x y cm */
|
||||
sprintf (str1, "q %ld 0 0 %ld %ld %ld cm\r\n", width, height, x, y);
|
||||
|
||||
pdf_stream_write_data (pdf_file, stream, str1, strlen (str1));
|
||||
pdf_stream_write_data (pdf_file, stream, str2, strlen (str2));
|
||||
pdf_stream_write_data (pdf_file, stream, & image->XObject_name [0],
|
||||
strlen (& image->XObject_name [0]));
|
||||
pdf_stream_write_data (pdf_file, stream, str3, strlen (str3));
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_g4_fax_image_callback (pdf_file_handle pdf_file,
|
||||
struct pdf_obj *stream,
|
||||
void *app_data)
|
||||
{
|
||||
struct pdf_g4_image *image = app_data;
|
||||
|
||||
#if 1
|
||||
pdf_stream_write_data (pdf_file, stream, image->data, image->len);
|
||||
#else
|
||||
unsigned long row = 0;
|
||||
unsigned char *ref;
|
||||
unsigned char *raw;
|
||||
|
||||
ref = NULL;
|
||||
raw = image->data;
|
||||
|
||||
while (row < image->Rows)
|
||||
{
|
||||
pdf_stream_write_data (pdf_file, stream, raw, image->rowbytes);
|
||||
|
||||
row++;
|
||||
ref = raw;
|
||||
raw += image->rowbytes;
|
||||
}
|
||||
/* $$$ generate and write EOFB code */
|
||||
/* $$$ flush any remaining buffered bits */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
|
||||
unsigned long Columns,
|
||||
unsigned long Rows,
|
||||
unsigned long rowbytes,
|
||||
int ImageMask,
|
||||
int BlackIs1, /* boolean, typ. false */
|
||||
unsigned char *data,
|
||||
unsigned long len)
|
||||
{
|
||||
struct pdf_g4_image *image;
|
||||
|
||||
struct pdf_obj *stream;
|
||||
struct pdf_obj *stream_dict;
|
||||
struct pdf_obj *decode_parms;
|
||||
|
||||
struct pdf_obj *content_stream;
|
||||
|
||||
image = pdf_calloc (sizeof (struct pdf_g4_image));
|
||||
|
||||
image->Columns = Columns;
|
||||
image->Rows = Rows;
|
||||
image->rowbytes = rowbytes;
|
||||
image->BlackIs1 = BlackIs1;
|
||||
image->data = data;
|
||||
image->len = len;
|
||||
|
||||
stream_dict = pdf_new_obj (PT_DICTIONARY);
|
||||
|
||||
stream = pdf_new_ind_ref (pdf_page->pdf_file,
|
||||
pdf_new_stream (pdf_page->pdf_file,
|
||||
stream_dict,
|
||||
& pdf_write_g4_fax_image_callback,
|
||||
image));
|
||||
|
||||
strcpy (& image->XObject_name [0], "Im ");
|
||||
image->XObject_name [2] = pdf_new_XObject (pdf_page, stream);
|
||||
|
||||
pdf_set_dict_entry (stream_dict, "Type", pdf_new_name ("XObject"));
|
||||
pdf_set_dict_entry (stream_dict, "Subtype", pdf_new_name ("Image"));
|
||||
pdf_set_dict_entry (stream_dict, "Name", pdf_new_name (& image->XObject_name [0]));
|
||||
pdf_set_dict_entry (stream_dict, "Width", pdf_new_integer (Columns));
|
||||
pdf_set_dict_entry (stream_dict, "Height", pdf_new_integer (Rows));
|
||||
pdf_set_dict_entry (stream_dict, "BitsPerComponent", pdf_new_integer (1));
|
||||
if (ImageMask)
|
||||
pdf_set_dict_entry (stream_dict, "ImageMask", pdf_new_bool (ImageMask));
|
||||
else
|
||||
pdf_set_dict_entry (stream_dict, "ColorSpace", pdf_new_name ("DeviceGray"));
|
||||
|
||||
decode_parms = pdf_new_obj (PT_DICTIONARY);
|
||||
|
||||
pdf_set_dict_entry (decode_parms,
|
||||
"K",
|
||||
pdf_new_integer (-1));
|
||||
|
||||
pdf_set_dict_entry (decode_parms,
|
||||
"Columns",
|
||||
pdf_new_integer (Columns));
|
||||
|
||||
pdf_set_dict_entry (decode_parms,
|
||||
"Rows",
|
||||
pdf_new_integer (Rows));
|
||||
|
||||
if (BlackIs1)
|
||||
pdf_set_dict_entry (decode_parms,
|
||||
"BlackIs1",
|
||||
pdf_new_bool (BlackIs1));
|
||||
|
||||
pdf_stream_add_filter (stream, "CCITTFaxDecode", decode_parms);
|
||||
|
||||
/* the following will write the stream, using our callback function to
|
||||
get the actual data */
|
||||
pdf_write_ind_obj (pdf_page->pdf_file, stream);
|
||||
|
||||
content_stream = pdf_new_ind_ref (pdf_page->pdf_file,
|
||||
pdf_new_stream (pdf_page->pdf_file,
|
||||
pdf_new_obj (PT_DICTIONARY),
|
||||
& pdf_write_g4_content_callback,
|
||||
image));
|
||||
|
||||
pdf_set_dict_entry (pdf_page->page_dict, "Contents", content_stream);
|
||||
|
||||
pdf_write_ind_obj (pdf_page->pdf_file, content_stream);
|
||||
}
|
||||
|
||||
525
pdf_prim.c
Normal file
525
pdf_prim.c
Normal file
@@ -0,0 +1,525 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libpdf.h"
|
||||
#include "libpdf_util.h"
|
||||
#include "libpdf_prim.h"
|
||||
#include "libpdf_private.h"
|
||||
|
||||
|
||||
struct pdf_array_elem
|
||||
{
|
||||
struct pdf_array_elem *next;
|
||||
struct pdf_obj *val;
|
||||
};
|
||||
|
||||
|
||||
struct pdf_array
|
||||
{
|
||||
struct pdf_array_elem *first;
|
||||
struct pdf_array_elem *last;
|
||||
};
|
||||
|
||||
|
||||
struct pdf_dict_entry
|
||||
{
|
||||
struct pdf_dict_entry *next;
|
||||
char *key;
|
||||
struct pdf_obj *val;
|
||||
};
|
||||
|
||||
|
||||
struct pdf_dict
|
||||
{
|
||||
struct pdf_dict_entry *first;
|
||||
};
|
||||
|
||||
|
||||
struct pdf_stream
|
||||
{
|
||||
struct pdf_obj *stream_dict;
|
||||
struct pdf_obj *length;
|
||||
pdf_stream_write_callback callback;
|
||||
void *app_data; /* arg to pass to callback */
|
||||
struct pdf_obj *filters; /* name or array of names */
|
||||
struct pdf_obj *decode_parms;
|
||||
};
|
||||
|
||||
|
||||
struct pdf_obj
|
||||
{
|
||||
/* these fields only apply to indirectly referenced objects */
|
||||
struct pdf_obj *prev;
|
||||
struct pdf_obj *next;
|
||||
unsigned long obj_num;
|
||||
unsigned long obj_gen;
|
||||
long int file_offset;
|
||||
|
||||
/* these fields apply to all objects */
|
||||
unsigned long ref_count;
|
||||
pdf_obj_type type;
|
||||
union {
|
||||
int bool;
|
||||
char *name;
|
||||
char *string;
|
||||
unsigned long integer;
|
||||
double real;
|
||||
struct pdf_obj *ind_ref;
|
||||
struct pdf_dict dict;
|
||||
struct pdf_array array;
|
||||
struct pdf_stream stream;
|
||||
} val;
|
||||
};
|
||||
|
||||
|
||||
struct pdf_obj *ref (struct pdf_obj *obj)
|
||||
{
|
||||
obj->ref_count++;
|
||||
return (obj);
|
||||
}
|
||||
|
||||
|
||||
void unref (struct pdf_obj *obj)
|
||||
{
|
||||
if ((--obj->ref_count) == 0)
|
||||
{
|
||||
/* $$$ free the object */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct pdf_obj *pdf_deref_ind_obj (struct pdf_obj *ind_obj)
|
||||
{
|
||||
pdf_assert (ind_obj->type == PT_IND_REF);
|
||||
return (ind_obj->val.ind_ref);
|
||||
}
|
||||
|
||||
|
||||
void pdf_set_dict_entry (struct pdf_obj *dict_obj, char *key, struct pdf_obj *val)
|
||||
{
|
||||
struct pdf_dict_entry *entry;
|
||||
|
||||
if (dict_obj->type == PT_IND_REF)
|
||||
dict_obj = pdf_deref_ind_obj (dict_obj);
|
||||
|
||||
pdf_assert (dict_obj->type == PT_DICTIONARY);
|
||||
|
||||
/* replacing existing entry? */
|
||||
for (entry = dict_obj->val.dict.first; entry; entry = entry->next)
|
||||
if (strcmp (entry->key, key) == 0)
|
||||
{
|
||||
unref (entry->val);
|
||||
entry->val = ref (val);
|
||||
return;
|
||||
}
|
||||
|
||||
/* new entry */
|
||||
entry = pdf_calloc (sizeof (struct pdf_dict_entry));
|
||||
|
||||
entry->next = dict_obj->val.dict.first;
|
||||
dict_obj->val.dict.first = entry;
|
||||
|
||||
entry->key = pdf_strdup (key);
|
||||
entry->val = ref (val);
|
||||
}
|
||||
|
||||
|
||||
struct pdf_obj *pdf_get_dict_entry (struct pdf_obj *dict_obj, char *key)
|
||||
{
|
||||
struct pdf_dict_entry *entry;
|
||||
|
||||
if (dict_obj->type == PT_IND_REF)
|
||||
dict_obj = pdf_deref_ind_obj (dict_obj);
|
||||
|
||||
pdf_assert (dict_obj->type == PT_DICTIONARY);
|
||||
|
||||
for (entry = dict_obj->val.dict.first; entry; entry = entry->next)
|
||||
if (strcmp (entry->key, key) == 0)
|
||||
return (entry->val);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
void pdf_add_array_elem (struct pdf_obj *array_obj, struct pdf_obj *val)
|
||||
{
|
||||
struct pdf_array_elem *elem = pdf_calloc (sizeof (struct pdf_array_elem));
|
||||
|
||||
if (array_obj->type == PT_IND_REF)
|
||||
array_obj = pdf_deref_ind_obj (array_obj);
|
||||
|
||||
pdf_assert (array_obj->type == PT_ARRAY);
|
||||
|
||||
elem->val = ref (val);
|
||||
|
||||
if (! array_obj->val.array.first)
|
||||
array_obj->val.array.first = elem;
|
||||
else
|
||||
array_obj->val.array.last->next = elem;
|
||||
|
||||
array_obj->val.array.last = elem;
|
||||
}
|
||||
|
||||
|
||||
struct pdf_obj *pdf_new_obj (pdf_obj_type type)
|
||||
{
|
||||
struct pdf_obj *obj = pdf_calloc (sizeof (struct pdf_obj));
|
||||
obj->type = type;
|
||||
return (obj);
|
||||
}
|
||||
|
||||
|
||||
struct pdf_obj *pdf_new_bool (int bool)
|
||||
{
|
||||
struct pdf_obj *obj = pdf_new_obj (PT_BOOL);
|
||||
obj->val.bool = bool;
|
||||
return (obj);
|
||||
}
|
||||
|
||||
|
||||
struct pdf_obj *pdf_new_name (char *name)
|
||||
{
|
||||
struct pdf_obj *obj = pdf_new_obj (PT_NAME);
|
||||
obj->val.name = pdf_strdup (name);
|
||||
return (obj);
|
||||
}
|
||||
|
||||
|
||||
struct pdf_obj *pdf_new_string (char *str)
|
||||
{
|
||||
struct pdf_obj *obj = pdf_new_obj (PT_STRING);
|
||||
obj->val.string = pdf_strdup (str);
|
||||
return (obj);
|
||||
}
|
||||
|
||||
|
||||
struct pdf_obj *pdf_new_integer (unsigned long val)
|
||||
{
|
||||
struct pdf_obj *obj = pdf_new_obj (PT_INTEGER);
|
||||
obj->val.integer = val;
|
||||
return (obj);
|
||||
}
|
||||
|
||||
|
||||
struct pdf_obj *pdf_new_real (double val)
|
||||
{
|
||||
struct pdf_obj *obj = pdf_new_obj (PT_REAL);
|
||||
obj->val.real = val;
|
||||
return (obj);
|
||||
}
|
||||
|
||||
|
||||
struct pdf_obj *pdf_new_stream (pdf_file_handle pdf_file,
|
||||
struct pdf_obj *stream_dict,
|
||||
pdf_stream_write_callback callback,
|
||||
void *app_data)
|
||||
{
|
||||
struct pdf_obj *obj = pdf_new_obj (PT_STREAM);
|
||||
|
||||
obj->val.stream.stream_dict = stream_dict;
|
||||
obj->val.stream.length = pdf_new_ind_ref (pdf_file, pdf_new_integer (0));
|
||||
pdf_set_dict_entry (obj->val.stream.stream_dict, "Length", obj->val.stream.length);
|
||||
|
||||
obj->val.stream.callback = callback;
|
||||
obj->val.stream.app_data = app_data;
|
||||
return (obj);
|
||||
}
|
||||
|
||||
|
||||
/* $$$ currently limited to one filter per stream */
|
||||
void pdf_stream_add_filter (struct pdf_obj *stream,
|
||||
char *filter_name,
|
||||
struct pdf_obj *decode_parms)
|
||||
{
|
||||
if (stream->type == PT_IND_REF)
|
||||
stream = pdf_deref_ind_obj (stream);
|
||||
|
||||
pdf_assert (stream->type == PT_STREAM);
|
||||
|
||||
pdf_set_dict_entry (stream->val.stream.stream_dict, "Filter", pdf_new_name (filter_name));
|
||||
if (decode_parms)
|
||||
pdf_set_dict_entry (stream->val.stream.stream_dict, "DecodeParms", decode_parms);
|
||||
}
|
||||
|
||||
|
||||
struct pdf_obj *pdf_new_ind_ref (pdf_file_handle pdf_file, struct pdf_obj *obj)
|
||||
{
|
||||
struct pdf_obj *ind_obj;
|
||||
|
||||
pdf_assert (obj->type != PT_IND_REF);
|
||||
|
||||
ind_obj = pdf_new_obj (PT_IND_REF);
|
||||
|
||||
ind_obj->type = PT_IND_REF;
|
||||
ind_obj->val.ind_ref = obj;
|
||||
|
||||
/* is there already an indirect reference to this object? */
|
||||
if (! obj->obj_num)
|
||||
{
|
||||
/* no, assign object number/generation and add to linked list */
|
||||
if (! pdf_file->first_ind_obj)
|
||||
{
|
||||
obj->obj_num = 1;
|
||||
pdf_file->first_ind_obj = pdf_file->last_ind_obj = obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj->obj_num = pdf_file->last_ind_obj->obj_num + 1;
|
||||
pdf_file->last_ind_obj->next = obj;
|
||||
obj->prev = pdf_file->last_ind_obj;
|
||||
pdf_file->last_ind_obj = obj;
|
||||
}
|
||||
}
|
||||
|
||||
return (ind_obj);
|
||||
}
|
||||
|
||||
|
||||
unsigned long pdf_get_integer (struct pdf_obj *obj)
|
||||
{
|
||||
if (obj->type == PT_IND_REF)
|
||||
obj = pdf_deref_ind_obj (obj);
|
||||
|
||||
pdf_assert (obj->type == PT_INTEGER);
|
||||
|
||||
return (obj->val.integer);
|
||||
}
|
||||
|
||||
void pdf_set_integer (struct pdf_obj *obj, unsigned long val)
|
||||
{
|
||||
if (obj->type == PT_IND_REF)
|
||||
obj = pdf_deref_ind_obj (obj);
|
||||
|
||||
pdf_assert (obj->type == PT_INTEGER);
|
||||
|
||||
obj->val.integer = val;
|
||||
}
|
||||
|
||||
|
||||
double pdf_get_real (struct pdf_obj *obj)
|
||||
{
|
||||
if (obj->type == PT_IND_REF)
|
||||
obj = pdf_deref_ind_obj (obj);
|
||||
|
||||
pdf_assert (obj->type == PT_REAL);
|
||||
|
||||
return (obj->val.real);
|
||||
}
|
||||
|
||||
void pdf_set_real (struct pdf_obj *obj, double val)
|
||||
{
|
||||
if (obj->type == PT_IND_REF)
|
||||
obj = pdf_deref_ind_obj (obj);
|
||||
|
||||
pdf_assert (obj->type == PT_REAL);
|
||||
|
||||
obj->val.real = val;
|
||||
}
|
||||
|
||||
|
||||
static int name_char_needs_quoting (char c)
|
||||
{
|
||||
return ((c < '!') || (c > '~') || (c == '/') || (c == '\\') ||
|
||||
(c == '(') || (c == ')') || (c == '<') || (c == '>') ||
|
||||
(c == '[') || (c == ']') || (c == '{') || (c == '}') ||
|
||||
(c == '%'));
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_name (pdf_file_handle pdf_file, char *s)
|
||||
{
|
||||
fprintf (pdf_file->f, "/");
|
||||
while (*s)
|
||||
if (name_char_needs_quoting (*s))
|
||||
fprintf (pdf_file->f, "#%02x", 0xff & *(s++));
|
||||
else
|
||||
fprintf (pdf_file->f, "%c", *(s++));
|
||||
fprintf (pdf_file->f, " ");
|
||||
}
|
||||
|
||||
|
||||
static int string_char_needs_quoting (char c)
|
||||
{
|
||||
return ((c < ' ') || (c > '~') || (c == '\\') ||
|
||||
(c == '(') || (c == ')'));
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_string (pdf_file_handle pdf_file, char *s)
|
||||
{
|
||||
fprintf (pdf_file->f, "(");
|
||||
while (*s)
|
||||
if (string_char_needs_quoting (*s))
|
||||
fprintf (pdf_file->f, "\\%03o", 0xff & *(s++));
|
||||
else
|
||||
fprintf (pdf_file->f, "%c", *(s++));
|
||||
fprintf (pdf_file->f, ") ");
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_real (pdf_file_handle pdf_file, double num)
|
||||
{
|
||||
/* $$$ not actually good enough, precision needs to be variable,
|
||||
and no exponent is allowed */
|
||||
fprintf (pdf_file->f, "%0f ", num);
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_ind_ref (pdf_file_handle pdf_file, struct pdf_obj *ind_obj)
|
||||
{
|
||||
struct pdf_obj *obj = pdf_deref_ind_obj (ind_obj);
|
||||
fprintf (pdf_file->f, "%ld %ld R ", obj->obj_num, obj->obj_gen);
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_array (pdf_file_handle pdf_file, struct pdf_obj *array_obj)
|
||||
{
|
||||
struct pdf_array_elem *elem;
|
||||
|
||||
pdf_assert (array_obj->type == PT_ARRAY);
|
||||
|
||||
fprintf (pdf_file->f, "[ ");
|
||||
for (elem = array_obj->val.array.first; elem; elem = elem->next)
|
||||
{
|
||||
pdf_write_obj (pdf_file, elem->val);
|
||||
fprintf (pdf_file->f, " ");
|
||||
}
|
||||
fprintf (pdf_file->f, "] ");
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_dict (pdf_file_handle pdf_file, struct pdf_obj *dict_obj)
|
||||
{
|
||||
struct pdf_dict_entry *entry;
|
||||
|
||||
pdf_assert (dict_obj->type == PT_DICTIONARY);
|
||||
|
||||
fprintf (pdf_file->f, "<<\r\n");
|
||||
for (entry = dict_obj->val.dict.first; entry; entry = entry->next)
|
||||
{
|
||||
pdf_write_name (pdf_file, entry->key);
|
||||
fprintf (pdf_file->f, " ");
|
||||
pdf_write_obj (pdf_file, entry->val);
|
||||
fprintf (pdf_file->f, "\r\n");
|
||||
}
|
||||
fprintf (pdf_file->f, ">>\r\n");
|
||||
}
|
||||
|
||||
|
||||
void pdf_stream_write_data (pdf_file_handle pdf_file,
|
||||
struct pdf_obj *stream,
|
||||
char *data,
|
||||
unsigned long len)
|
||||
{
|
||||
while (len)
|
||||
{
|
||||
unsigned long l2 = fwrite (data, 1, len, pdf_file->f);
|
||||
data += l2;
|
||||
len -= l2;
|
||||
if (ferror (pdf_file->f))
|
||||
pdf_fatal ("error writing stream data\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_stream (pdf_file_handle pdf_file, struct pdf_obj *stream)
|
||||
{
|
||||
unsigned long begin_pos, end_pos;
|
||||
|
||||
pdf_assert (stream->type == PT_STREAM);
|
||||
|
||||
pdf_write_dict (pdf_file, stream->val.stream.stream_dict);
|
||||
fprintf (pdf_file->f, "stream\r\n");
|
||||
begin_pos = ftell (pdf_file->f);
|
||||
stream->val.stream.callback (pdf_file,
|
||||
stream,
|
||||
stream->val.stream.app_data);
|
||||
end_pos = ftell (pdf_file->f);
|
||||
fprintf (pdf_file->f, "\r\nendstream\r\n");
|
||||
|
||||
pdf_set_integer (stream->val.stream.length, end_pos - begin_pos);
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_obj (pdf_file_handle pdf_file, struct pdf_obj *obj)
|
||||
{
|
||||
switch (obj->type)
|
||||
{
|
||||
case PT_NULL:
|
||||
fprintf (pdf_file->f, "null ");
|
||||
break;
|
||||
case PT_BOOL:
|
||||
if (obj->val.bool)
|
||||
fprintf (pdf_file->f, "true ");
|
||||
else
|
||||
fprintf (pdf_file->f, "false ");
|
||||
break;
|
||||
case PT_NAME:
|
||||
pdf_write_name (pdf_file, obj->val.name);
|
||||
break;
|
||||
case PT_STRING:
|
||||
pdf_write_string (pdf_file, obj->val.string);
|
||||
break;
|
||||
case PT_INTEGER:
|
||||
fprintf (pdf_file->f, "%ld ", obj->val.integer);
|
||||
break;
|
||||
case PT_REAL:
|
||||
pdf_write_real (pdf_file, obj->val.real);
|
||||
break;
|
||||
case PT_IND_REF:
|
||||
pdf_write_ind_ref (pdf_file, obj);
|
||||
break;
|
||||
case PT_DICTIONARY:
|
||||
pdf_write_dict (pdf_file, obj);
|
||||
break;
|
||||
case PT_ARRAY:
|
||||
pdf_write_array (pdf_file, obj);
|
||||
break;
|
||||
case PT_STREAM:
|
||||
pdf_write_stream (pdf_file, obj);
|
||||
break;
|
||||
default:
|
||||
pdf_fatal ("bad object type\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_ind_obj (pdf_file_handle pdf_file, struct pdf_obj *ind_obj)
|
||||
{
|
||||
struct pdf_obj *obj;
|
||||
|
||||
if (ind_obj->type == PT_IND_REF)
|
||||
obj = pdf_deref_ind_obj (ind_obj);
|
||||
else
|
||||
obj = ind_obj;
|
||||
|
||||
obj->file_offset = ftell (pdf_file->f);
|
||||
fprintf (pdf_file->f, "%ld %ld obj\r\n", obj->obj_num, obj->obj_gen);
|
||||
pdf_write_obj (pdf_file, obj);
|
||||
fprintf (pdf_file->f, "endobj\r\n");
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_all_ind_obj (pdf_file_handle pdf_file)
|
||||
{
|
||||
struct pdf_obj *ind_obj;
|
||||
for (ind_obj = pdf_file->first_ind_obj; ind_obj; ind_obj = ind_obj->next)
|
||||
if (! ind_obj->file_offset)
|
||||
pdf_write_ind_obj (pdf_file, ind_obj);
|
||||
}
|
||||
|
||||
|
||||
unsigned long pdf_write_xref (pdf_file_handle pdf_file)
|
||||
{
|
||||
struct pdf_obj *ind_obj;
|
||||
pdf_file->xref_offset = ftell (pdf_file->f);
|
||||
fprintf (pdf_file->f, "xref\r\n");
|
||||
fprintf (pdf_file->f, "0 %ld\r\n", pdf_file->last_ind_obj->obj_num + 1);
|
||||
fprintf (pdf_file->f, "0000000000 65535 f\r\n");
|
||||
for (ind_obj = pdf_file->first_ind_obj; ind_obj; ind_obj = ind_obj->next)
|
||||
fprintf (pdf_file->f, "%010ld 00000 n\r\n", ind_obj->file_offset);
|
||||
return (pdf_file->last_ind_obj->obj_num + 1);
|
||||
}
|
||||
|
||||
|
||||
100
pdf_prim.h
Normal file
100
pdf_prim.h
Normal file
@@ -0,0 +1,100 @@
|
||||
typedef enum
|
||||
{
|
||||
PT_BAD,
|
||||
|
||||
/* scalar */
|
||||
PT_NULL,
|
||||
PT_BOOL,
|
||||
PT_NAME,
|
||||
PT_STRING,
|
||||
PT_INTEGER,
|
||||
PT_REAL,
|
||||
PT_IND_REF,
|
||||
|
||||
/* composite */
|
||||
PT_DICTIONARY,
|
||||
PT_ARRAY,
|
||||
PT_STREAM
|
||||
} pdf_obj_type;
|
||||
|
||||
|
||||
struct pdf_obj;
|
||||
|
||||
|
||||
typedef void (*pdf_stream_write_callback)(pdf_file_handle pdf_file,
|
||||
struct pdf_obj *stream,
|
||||
void *app_data);
|
||||
|
||||
|
||||
void pdf_set_dict_entry (struct pdf_obj *dict_obj, char *key, struct pdf_obj *val);
|
||||
struct pdf_obj *pdf_get_dict_entry (struct pdf_obj *dict_obj, char *key);
|
||||
|
||||
|
||||
void pdf_add_array_elem (struct pdf_obj *array_obj, struct pdf_obj *val);
|
||||
|
||||
|
||||
/* Create a new object that will NOT be used indirectly */
|
||||
struct pdf_obj *pdf_new_obj (pdf_obj_type type);
|
||||
|
||||
struct pdf_obj *pdf_new_bool (int bool);
|
||||
|
||||
struct pdf_obj *pdf_new_name (char *name);
|
||||
|
||||
struct pdf_obj *pdf_new_string (char *str);
|
||||
|
||||
struct pdf_obj *pdf_new_integer (unsigned long val);
|
||||
|
||||
struct pdf_obj *pdf_new_real (double val);
|
||||
|
||||
|
||||
/* Create a new indirect object */
|
||||
struct pdf_obj *pdf_new_ind_ref (pdf_file_handle pdf_file, struct pdf_obj *obj);
|
||||
|
||||
/* get the object referenced by an indirect reference */
|
||||
struct pdf_obj *pdf_deref_ind_obj (struct pdf_obj *ind_obj);
|
||||
|
||||
|
||||
unsigned long pdf_get_integer (struct pdf_obj *obj);
|
||||
void pdf_set_integer (struct pdf_obj *obj, unsigned long val);
|
||||
|
||||
|
||||
double pdf_get_real (struct pdf_obj *obj);
|
||||
void pdf_set_real (struct pdf_obj *obj, double val);
|
||||
|
||||
|
||||
/* The callback will be called when the stream data is to be written to the
|
||||
file. app_data will be passed as an argument to the callback. */
|
||||
struct pdf_obj *pdf_new_stream (pdf_file_handle pdf_file,
|
||||
struct pdf_obj *stream_dict,
|
||||
pdf_stream_write_callback callback,
|
||||
void *app_data);
|
||||
|
||||
/* The callback should call pdf_stream_write_data to write the actual
|
||||
stream data. */
|
||||
void pdf_stream_write_data (pdf_file_handle pdf_file,
|
||||
struct pdf_obj *stream,
|
||||
char *data,
|
||||
unsigned long len);
|
||||
|
||||
void pdf_stream_add_filter (struct pdf_obj *stream,
|
||||
char *filter_name,
|
||||
struct pdf_obj *decode_parms);
|
||||
|
||||
|
||||
/* Write the object to the file */
|
||||
void pdf_write_obj (pdf_file_handle pdf_file, struct pdf_obj *obj);
|
||||
|
||||
|
||||
/* Write the indirect object to the file. For most objects this should
|
||||
be done by pdf_write_all_ind_obj() when the file is being closed, but for
|
||||
large objects such as streams, it's probably better to do it as soon as the
|
||||
object is complete. */
|
||||
void pdf_write_ind_obj (pdf_file_handle pdf_file, struct pdf_obj *ind_obj);
|
||||
|
||||
|
||||
/* Write all indirect objects that haven't already been written to the file. */
|
||||
void pdf_write_all_ind_obj (pdf_file_handle pdf_file);
|
||||
|
||||
|
||||
/* Write the cross reference table, and return the maximum object number */
|
||||
unsigned long pdf_write_xref (pdf_file_handle pdf_file);
|
||||
32
pdf_private.h
Normal file
32
pdf_private.h
Normal file
@@ -0,0 +1,32 @@
|
||||
struct pdf_page
|
||||
{
|
||||
pdf_file_handle pdf_file;
|
||||
struct pdf_obj *page_dict;
|
||||
struct pdf_obj *media_box;
|
||||
struct pdf_obj *procset;
|
||||
struct pdf_obj *resources;
|
||||
|
||||
char last_XObject_name;
|
||||
struct pdf_obj *XObject_dict;
|
||||
};
|
||||
|
||||
|
||||
struct pdf_pages
|
||||
{
|
||||
struct pdf_obj *pages_dict;
|
||||
struct pdf_obj *kids;
|
||||
struct pdf_obj *count;
|
||||
};
|
||||
|
||||
|
||||
struct pdf_file
|
||||
{
|
||||
FILE *f;
|
||||
struct pdf_obj *first_ind_obj;
|
||||
struct pdf_obj *last_ind_obj;
|
||||
long int xref_offset;
|
||||
struct pdf_obj *catalog;
|
||||
struct pdf_obj *info;
|
||||
struct pdf_pages *root;
|
||||
struct pdf_obj *trailer_dict;
|
||||
};
|
||||
37
pdf_util.c
Normal file
37
pdf_util.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libpdf.h"
|
||||
#include "libpdf_util.h"
|
||||
|
||||
|
||||
void pdf_fatal (char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
vfprintf (stderr, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
exit (2);
|
||||
}
|
||||
|
||||
|
||||
void *pdf_calloc (long int size)
|
||||
{
|
||||
void *m = calloc (1, size);
|
||||
if (! m)
|
||||
pdf_fatal ("failed to allocate memory\n");
|
||||
return (m);
|
||||
}
|
||||
|
||||
|
||||
char *pdf_strdup (char *s)
|
||||
{
|
||||
unsigned long len = strlen (s);
|
||||
char *s2 = pdf_calloc (len + 1);
|
||||
strcpy (s2, s);
|
||||
return (s2);
|
||||
}
|
||||
11
pdf_util.h
Normal file
11
pdf_util.h
Normal file
@@ -0,0 +1,11 @@
|
||||
void pdf_fatal (char *fmt, ...);
|
||||
|
||||
void *pdf_calloc (long int size);
|
||||
|
||||
char *pdf_strdup (char *s);
|
||||
|
||||
#define pdf_assert(cond) do \
|
||||
{ \
|
||||
if (! (cond)) \
|
||||
pdf_fatal ("assert at %s(%d)\n", __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
Reference in New Issue
Block a user