mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2024-12-26 13:28:22 +01:00
Save work.
This commit is contained in:
parent
11588ce2f5
commit
e2e2192ea9
6
TODO.md
Normal file
6
TODO.md
Normal file
@ -0,0 +1,6 @@
|
||||
To-Do List
|
||||
==========
|
||||
|
||||
- Binary data/strings: needed for certain values, particular for the File ID
|
||||
and user/owner passwords
|
||||
- Copy methods for array, dict, object, page, value
|
@ -14,19 +14,6 @@
|
||||
#include "pdfio-private.h"
|
||||
|
||||
|
||||
//
|
||||
// Array structure
|
||||
//
|
||||
|
||||
struct _pdfio_array_s
|
||||
{
|
||||
pdfio_file_t *pdf; // PDF file
|
||||
size_t num_values, // Number of values in use
|
||||
alloc_values; // Number of allocated values
|
||||
_pdfio_value_t *values; // Array of values
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Local functions...
|
||||
//
|
||||
@ -167,6 +154,21 @@ pdfioArrayAppendString(
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'pdfioArrayCopy()' - Copy an array.
|
||||
//
|
||||
|
||||
pdfio_array_t * // O - New array or `NULL` on error
|
||||
pdfioArrayCopy(pdfio_file_t *pdf, // I - PDF file
|
||||
pdfio_array_t *a) // I - Original array
|
||||
{
|
||||
// TODO: Implement me
|
||||
(void)pdf;
|
||||
(void)a;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'pdfioArrayCreate()' - Create an empty array.
|
||||
//
|
||||
@ -365,6 +367,34 @@ _pdfioArrayGetValue(pdfio_array_t *a, // I - Array
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '_pdfioArrayWrite()' - Write an array to a PDF file.
|
||||
//
|
||||
|
||||
bool // O - `true` on success, `false` otherwise
|
||||
_pdfioArrayWrite(pdfio_array_t *a) // I - Array
|
||||
{
|
||||
pdfio_file_t *pdf = a->pdf; // PDF file
|
||||
size_t i; // Looping var
|
||||
_pdfio_value_t *v; // Current value
|
||||
|
||||
|
||||
// Arrays are surrounded by square brackets ([ ... ])
|
||||
if (!_pdfioFilePuts(pdf, "["))
|
||||
return (false);
|
||||
|
||||
// Write each value...
|
||||
for (i = a->num_values, v = a->values; i > 0; i --, v ++)
|
||||
{
|
||||
if (!_pdfioValueWrite(pdf, v))
|
||||
return (false);
|
||||
}
|
||||
|
||||
// Closing bracket...
|
||||
return (_pdfioFilePuts(pdf, "]"));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'append_value()' - Append a value.
|
||||
//
|
||||
|
@ -65,6 +65,26 @@ _pdfioFileError(pdfio_file_t *pdf, // I - PDF file
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '_pdfioFileFlush()' - Flush any pending write data.
|
||||
//
|
||||
|
||||
bool // O - `true` on success, `false` on failure
|
||||
_pdfioFileFlush(pdfio_file_t *pdf) // I - PDF file
|
||||
{
|
||||
if (pdf->bufptr > pdf->buffer)
|
||||
{
|
||||
if (!write_buffer(pdf, pdf->buffer, (size_t)(pdf->bufptr - pdf->buffer)))
|
||||
return (false);
|
||||
|
||||
pdf->bufpos += pdf->bufptr - pdf->buffer;
|
||||
pdf->bufptr = pdf->buffer;
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '_pdfioFileGetChar()' - Get a character from a PDF file.
|
||||
//
|
||||
@ -85,6 +105,42 @@ _pdfioFileGetChar(pdfio_file_t *pdf) // I - PDF file
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '_pdfioFilePrintf()' - Write a formatted string to a PDF file.
|
||||
//
|
||||
|
||||
bool // O - `true` on success, `false` on failure
|
||||
_pdfioFilePrintf(pdfio_file_t *pdf, // I - PDF file
|
||||
const char *format, // I - `printf`-style format string
|
||||
...) // I - Additional arguments as needed
|
||||
{
|
||||
char buffer[8102]; // String buffer
|
||||
va_list ap; // Argument list
|
||||
|
||||
|
||||
// Format the string...
|
||||
va_start(ap, format);
|
||||
vsnprintf(buffer, sizeof(buffer), format, ap);
|
||||
va_end(ap);
|
||||
|
||||
// Write it...
|
||||
return (_pdfioFileWrite(pdf, buffer, strlen(buffer)));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '_pdfioFilePuts()' - Write a literal string to a PDF file.
|
||||
//
|
||||
|
||||
bool // O - `true` on success, `false` on failure
|
||||
_pdfioFilePuts(pdfio_file_t *pdf, // I - PDF file
|
||||
const char *s) // I - Literal string
|
||||
{
|
||||
// Write it...
|
||||
return (_pdfioFileWrite(pdf, s, strlen(s)));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '_pdfioFileRead()' - Read from a PDF file.
|
||||
//
|
||||
@ -152,7 +208,7 @@ _pdfioFileSeek(pdfio_file_t *pdf, // I - PDF file
|
||||
whence = SEEK_SET;
|
||||
}
|
||||
|
||||
if (pdf->mode == PDFIO_MODE_READ)
|
||||
if (pdf->mode == _PDFIO_MODE_READ)
|
||||
{
|
||||
// Reading, see if we already have the data we need...
|
||||
if (whence != SEEK_END && offset >= pdf->bufpos && offset < (pdf->bufpos + pdf->bufend - pdf->buffer))
|
||||
@ -217,16 +273,9 @@ _pdfioFileWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
if (bytes > (size_t)(pdf->bufend - pdf->bufptr))
|
||||
{
|
||||
// No room, flush any current data...
|
||||
if (pdf->bufptr > pdf->buffer)
|
||||
{
|
||||
if (!write_buffer(pdf, pdf->buffer, (size_t)(pdf->bufptr - pdf->buffer)))
|
||||
if (!_pdfioFileFlush(pdf))
|
||||
return (false);
|
||||
|
||||
pdf->bufpos += pdf->bufptr - pdf->buffer;
|
||||
}
|
||||
|
||||
pdf->bufptr = pdf->buffer;
|
||||
|
||||
if (bytes >= sizeof(pdf->buffer))
|
||||
{
|
||||
// Write directly...
|
||||
|
76
pdfio-dict.c
76
pdfio-dict.c
@ -14,25 +14,6 @@
|
||||
#include "pdfio-private.h"
|
||||
|
||||
|
||||
//
|
||||
// Dictionary structures
|
||||
//
|
||||
|
||||
typedef struct _pdfio_pair_s // Key/value pair
|
||||
{
|
||||
const char *key; // Key string
|
||||
_pdfio_value_t value; // Value
|
||||
} _pdfio_pair_t;
|
||||
|
||||
struct _pdfio_dict_s
|
||||
{
|
||||
pdfio_file_t *pdf; // PDF file
|
||||
size_t num_pairs, // Number of pairs in use
|
||||
alloc_pairs; // Number of allocated pairs
|
||||
_pdfio_pair_t *pairs; // Array of pairs
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Local functions...
|
||||
//
|
||||
@ -40,6 +21,21 @@ struct _pdfio_dict_s
|
||||
static int compare_pairs(_pdfio_pair_t *a, _pdfio_pair_t *b);
|
||||
|
||||
|
||||
//
|
||||
// 'pdfioDictCopy()' - Copy a dictionary to a PDF file.
|
||||
//
|
||||
|
||||
pdfio_dict_t * // O - New dictionary
|
||||
pdfioDictCopy(pdfio_file_t *pdf, // I - PDF file
|
||||
pdfio_dict_t *dict) // I - Original dictionary
|
||||
{
|
||||
// TODO: Implement me
|
||||
(void)pdf;
|
||||
(void)dict;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'pdfioDictCreate()' - Create a dictionary to hold key/value pairs.
|
||||
//
|
||||
@ -531,6 +527,48 @@ _pdfioDictSetValue(
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '_pdfioDictWrite()' - Write a dictionary to a PDF file.
|
||||
//
|
||||
|
||||
bool // O - `true` on success, `false` on failure
|
||||
_pdfioDictWrite(pdfio_dict_t *dict, // I - Dictionary
|
||||
off_t *length) // I - Offset to length value
|
||||
{
|
||||
pdfio_file_t *pdf = dict->pdf; // PDF file
|
||||
size_t i; // Looping var
|
||||
_pdfio_pair_t *pair; // Current key/value pair
|
||||
|
||||
|
||||
if (length)
|
||||
*length = 0;
|
||||
|
||||
// Dictionaries are bounded by "<<" and ">>"...
|
||||
if (!_pdfioFilePuts(pdf, "<<"))
|
||||
return (false);
|
||||
|
||||
// Write all of the key/value pairs...
|
||||
for (i = dict->num_pairs, pair = dict->pairs; i > 0; i --, pair ++)
|
||||
{
|
||||
if (!_pdfioFilePrintf(pdf, "/%s", pair->key))
|
||||
return (false);
|
||||
|
||||
if (length && !strcmp(pair->key, "Length"))
|
||||
{
|
||||
// Writing an object dictionary with an undefined length
|
||||
*length = _pdfioFileTell(pdf);
|
||||
if (!_pdfioFilePuts(pdf, " 999999999"))
|
||||
return (false);
|
||||
}
|
||||
else if (!_pdfioValueWrite(pdf, &pair->value))
|
||||
return (false);
|
||||
}
|
||||
|
||||
// Close it up...
|
||||
return (_pdfioFilePuts(pdf, ">>"));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'compare_pairs()' - Compare the keys for two pairs.
|
||||
//
|
||||
|
293
pdfio-file.c
293
pdfio-file.c
@ -12,95 +12,348 @@
|
||||
//
|
||||
|
||||
#include "pdfio-private.h"
|
||||
#ifndef O_BINARY
|
||||
# define O_BINARY 0
|
||||
#endif // !O_BINARY
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// Local functions...
|
||||
//
|
||||
|
||||
bool pdfioFileClose(pdfio_file_t *pdf)
|
||||
static bool write_trailer(pdfio_file_t *pdf);
|
||||
|
||||
|
||||
//
|
||||
// 'pdfioFileClose()' - Close a PDF file and free all memory used for it.
|
||||
//
|
||||
|
||||
bool // O - `true` on success and `false` on failure
|
||||
pdfioFileClose(pdfio_file_t *pdf) // I - PDF file
|
||||
{
|
||||
bool ret = true; // Return value
|
||||
size_t i; // Looping var
|
||||
|
||||
|
||||
// Range check input
|
||||
if (!pdf)
|
||||
return (false);
|
||||
|
||||
// Close the file itself...
|
||||
if (pdf->mode == _PDFIO_MODE_WRITE)
|
||||
ret = write_trailer(pdf);
|
||||
|
||||
if (close(pdf->fd) < 0)
|
||||
ret = false;
|
||||
|
||||
// Free all data...
|
||||
free(pdf->filename);
|
||||
free(pdf->version);
|
||||
|
||||
for (i = 0; i < pdf->num_arrays; i ++)
|
||||
_pdfioArrayDelete(pdf->arrays[i]);
|
||||
free(pdf->arrays);
|
||||
|
||||
for (i = 0; i < pdf->num_dicts; i ++)
|
||||
_pdfioDictDelete(pdf->dicts[i]);
|
||||
free(pdf->dicts);
|
||||
|
||||
for (i = 0; i < pdf->num_objs; i ++)
|
||||
_pdfioObjDelete(pdf->objs[i]);
|
||||
free(pdf->objs);
|
||||
|
||||
free(pdf->pages);
|
||||
|
||||
for (i = 0; i < pdf->num_strings; i ++)
|
||||
free(pdf->strings[i]);
|
||||
free(pdf->strings);
|
||||
|
||||
free(pdf);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// 'pdfioFileCreate()' - Create a PDF file.
|
||||
//
|
||||
|
||||
pdfio_obj_t *pdfioFileCreateObject(pdfio_file_t *file, pdfio_dict_t *dict)
|
||||
pdfio_file_t * // O - PDF file or `NULL` on error
|
||||
pdfioFileCreate(
|
||||
const char *filename, // I - Filename
|
||||
const char *version, // I - PDF version number or `NULL` for default (2.0)
|
||||
pdfio_error_cb_t error_cb, // I - Error callback or `NULL` for default
|
||||
void *error_data) // I - Error callback data, if any
|
||||
{
|
||||
pdfio_file_t *pdf; // PDF file
|
||||
|
||||
|
||||
// Range check input...
|
||||
if (!filename)
|
||||
return (NULL);
|
||||
|
||||
if (!version)
|
||||
version = "2.0";
|
||||
|
||||
if (!error_cb)
|
||||
{
|
||||
error_cb = _pdfioFileDefaultError;
|
||||
error_data = NULL;
|
||||
}
|
||||
|
||||
// Allocate a PDF file structure...
|
||||
if ((pdf = (pdfio_file_t *)calloc(1, sizeof(pdfio_file_t))) == NULL)
|
||||
{
|
||||
pdfio_file_t temp; // Dummy file
|
||||
char message[8192]; // Message string
|
||||
|
||||
temp.filename = (char *)filename;
|
||||
snprintf(message, sizeof(message), "Unable to allocate memory for PDF file - %s", strerror(errno));
|
||||
(error_cb)(&temp, message, error_data);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
pdf->filename = strdup(filename);
|
||||
pdf->version = strdup(version);
|
||||
pdf->mode = _PDFIO_MODE_WRITE;
|
||||
pdf->error_cb = error_cb;
|
||||
pdf->error_data = error_data;
|
||||
|
||||
// Create the file...
|
||||
if ((pdf->fd = open(filename, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, 0666)) < 0)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to create file - %s", strerror(errno));
|
||||
free(pdf->filename);
|
||||
free(pdf->version);
|
||||
free(pdf);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Write a standard PDF header...
|
||||
if (!_pdfioFilePrintf(pdf, "%%PDF-%s\n%%\342\343\317\323\n", version))
|
||||
{
|
||||
pdfioFileClose(pdf);
|
||||
unlink(filename);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (pdf);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// 'pdfioFileCreateObject()' - Create a new object in a PDF file.
|
||||
//
|
||||
|
||||
pdfio_obj_t *pdfioFileCreatePage(pdfio_t *pdf, pdfio_dict_t *dict)
|
||||
pdfio_obj_t * // O - New object
|
||||
pdfioFileCreateObject(
|
||||
pdfio_file_t *pdf, // I - PDF file
|
||||
pdfio_dict_t *dict) // I - Object dictionary
|
||||
{
|
||||
pdfio_obj_t *obj; // New object
|
||||
|
||||
|
||||
// Range check input...
|
||||
if (!pdf || !dict)
|
||||
{
|
||||
if (pdf)
|
||||
_pdfioFileError(pdf, "Missing object dictionary.");
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (dict->pdf != pdf)
|
||||
dict = pdfioDictCopy(pdf, dict); // Copy dictionary to new PDF
|
||||
|
||||
// Allocate memory for the object...
|
||||
if ((obj = (pdfio_obj_t *)calloc(1, sizeof(pdfio_obj_t))) == NULL)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to allocate memory for object - %s", strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Expand the objects array as needed
|
||||
if (pdf->num_objs >= pdf->alloc_objs)
|
||||
{
|
||||
pdfio_obj_t **temp = (pdfio_obj_t **)realloc(pdf->objs, (pdf->alloc_objs + 32) * sizeof(pdfio_obj_t *));
|
||||
|
||||
if (!temp)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to allocate memory for object - %s", strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
pdf->objs = temp;
|
||||
pdf->alloc_objs += 32;
|
||||
}
|
||||
|
||||
pdf->objs[pdf->num_objs ++] = obj;
|
||||
|
||||
// Initialize the object...
|
||||
obj->pdf = pdf;
|
||||
obj->number = pdf->num_objs;
|
||||
obj->dict = dict;
|
||||
obj->offset = _pdfioFileTell(pdf);
|
||||
|
||||
// Don't write anything just yet...
|
||||
return (obj);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// 'pdfioFileCreatePage()' - Create a page in a PDF file.
|
||||
//
|
||||
|
||||
void _pdfioFileDelete(pdfio_file_t *file)
|
||||
pdfio_obj_t * // O - New object
|
||||
pdfioFileCreatePage(pdfio_file_t *pdf, // I - PDF file
|
||||
pdfio_dict_t *dict) // I - Page dictionary
|
||||
{
|
||||
// TODO: Implement me
|
||||
(void)pdf;
|
||||
(void)dict;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// 'pdfioFileGetName()' - Get a PDF's filename.
|
||||
//
|
||||
|
||||
const char *pdfioFileGetName(pdfio_file_t *pdf)
|
||||
const char * // O - Filename
|
||||
pdfioFileGetName(pdfio_file_t *pdf) // I - PDF file
|
||||
{
|
||||
return (pdf ? pdf->filename : NULL);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// 'pdfioFileGetNumObjects()' - Get the number of objects in a PDF file.
|
||||
//
|
||||
|
||||
int pdfioFileGetNumObjects(pdfio_file_t *pdf)
|
||||
size_t // O - Number of objects
|
||||
pdfioFileGetNumObjects(
|
||||
pdfio_file_t *pdf) // I - PDF file
|
||||
{
|
||||
return (pdf ? pdf->num_objs : 0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// 'pdfioFileGetNumPages()' - Get the number of pages in a PDF file.
|
||||
//
|
||||
|
||||
int pdfioFileGetNumPages(pdfio_file_t *pdf)
|
||||
size_t // O - Number of pages
|
||||
pdfioFileGetNumPages(pdfio_file_t *pdf) // I - PDF file
|
||||
{
|
||||
return (pdf ? pdf->num_pages : 0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// 'pdfioFileGetObject()' - Get an object from a PDF file.
|
||||
//
|
||||
|
||||
pdfio_obj_t *pdfioFileGetObject(pdfio_file_t *pdf, int number)
|
||||
pdfio_obj_t * // O - Object
|
||||
pdfioFileGetObject(pdfio_file_t *pdf, // I - PDF file
|
||||
size_t number) // I - Object number (starting at 1)
|
||||
{
|
||||
if (!pdf || number < 1 || number > pdf->num_objs)
|
||||
return (NULL);
|
||||
else
|
||||
return (pdf->objs[number - 1]);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// 'pdfioFileGetPage()' - Get a page object from a PDF file.
|
||||
//
|
||||
|
||||
pdfio_obj_t *pdfioFileGetPage(pdfio_file_t *pdf, int number)
|
||||
pdfio_obj_t * // O - Object
|
||||
pdfioFileGetPage(pdfio_file_t *pdf, // I - PDF file
|
||||
size_t number) // I - Page number (starting at 1)
|
||||
{
|
||||
if (!pdf || number < 1 || number > pdf->num_pages)
|
||||
return (NULL);
|
||||
else
|
||||
return (pdf->pages[number - 1]);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// '()' - Get the PDF version number for a PDF file.
|
||||
//
|
||||
|
||||
pdfio_file_t *pdfioFileOpen(const char *filename, const char *mode, pdfio_error_cb_t error_cb, void *error_data)
|
||||
const char * // O - Version number or `NULL`
|
||||
pdfioFileGetVersion(
|
||||
pdfio_file_t *pdf) // I - PDF file
|
||||
{
|
||||
return (pdf ? pdf->version : NULL);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'pdfioFileOpen()' - Open a PDF file for reading.
|
||||
//
|
||||
|
||||
pdfio_file_t * // O - PDF file
|
||||
pdfioFileOpen(
|
||||
const char *filename, // I - Filename
|
||||
pdfio_error_cb_t error_cb, // I - Error callback or `NULL` for default
|
||||
void *error_data) // I - Error callback data, if any
|
||||
{
|
||||
pdfio_file_t *pdf; // PDF file
|
||||
|
||||
|
||||
// Range check input...
|
||||
if (!filename)
|
||||
return (NULL);
|
||||
|
||||
if (!error_cb)
|
||||
{
|
||||
error_cb = _pdfioFileDefaultError;
|
||||
error_data = NULL;
|
||||
}
|
||||
|
||||
// Allocate a PDF file structure...
|
||||
if ((pdf = (pdfio_file_t *)calloc(1, sizeof(pdfio_file_t))) == NULL)
|
||||
{
|
||||
pdfio_file_t temp; // Dummy file
|
||||
char message[8192]; // Message string
|
||||
|
||||
temp.filename = (char *)filename;
|
||||
snprintf(message, sizeof(message), "Unable to allocate memory for PDF file - %s", strerror(errno));
|
||||
(error_cb)(&temp, message, error_data);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
pdf->filename = strdup(filename);
|
||||
pdf->mode = _PDFIO_MODE_READ;
|
||||
pdf->error_cb = error_cb;
|
||||
pdf->error_data = error_data;
|
||||
|
||||
// Open the file...
|
||||
if ((pdf->fd = open(filename, O_RDONLY | O_BINARY)) < 0)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to open file - %s", strerror(errno));
|
||||
free(pdf->filename);
|
||||
free(pdf);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// TODO: read header, trailer, and xref table...
|
||||
return (pdf);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'write_trailer()' - Write the PDF catalog object, xref table, and trailer.
|
||||
//
|
||||
|
||||
static bool // O - `true` on success, `false` on failure
|
||||
write_trailer(pdfio_file_t *pdf) // I - PDF file
|
||||
{
|
||||
// TODO: Write trailer
|
||||
(void)pdf;
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
@ -14,8 +14,6 @@
|
||||
#include "pdfio-private.h"
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 'pdfioObjClose()' - Close an object, writing any data as needed to the PDF
|
||||
// file.
|
||||
@ -24,6 +22,9 @@
|
||||
bool // O - `true` on success, `false` on failure
|
||||
pdfioObjClose(pdfio_obj_t *obj) // I - Object
|
||||
{
|
||||
// TODO: Implement me
|
||||
(void)obj;
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
@ -37,6 +38,11 @@ pdfioObjCreateStream(
|
||||
pdfio_obj_t *obj, // I - Object
|
||||
pdfio_filter_t filter) // I - Type of compression to apply
|
||||
{
|
||||
// TODO: Implement me
|
||||
(void)obj;
|
||||
(void)filter;
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -45,7 +51,7 @@ pdfioObjCreateStream(
|
||||
//
|
||||
|
||||
void
|
||||
_pdfioObjDelete(pdfio_object_t *obj) // I - Object
|
||||
_pdfioObjDelete(pdfio_obj_t *obj) // I - Object
|
||||
{
|
||||
if (obj)
|
||||
pdfioStreamClose(obj->stream);
|
||||
@ -69,29 +75,38 @@ pdfioObjGetDict(pdfio_obj_t *obj) // I - Object
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// 'pdfioObjGetGeneration()' - Get the object's generation number.
|
||||
//
|
||||
|
||||
int pdfioObjGetGeneration(pdfio_obj_t *obj)
|
||||
size_t // O - Generation number (0 to 65535)
|
||||
pdfioObjGetGeneration(pdfio_obj_t *obj) // I - Object
|
||||
{
|
||||
return (obj ? obj->generation : 0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// 'pdfioObjGetNumber()' - Get the object's number.
|
||||
//
|
||||
|
||||
int pdfioObjGetNumber(pdfio_obj_t *obj)
|
||||
size_t // O - Object number (1 to 9999999999)
|
||||
pdfioObjGetNumber(pdfio_obj_t *obj) // I - Object
|
||||
{
|
||||
return (obj ? obj->number : 0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// 'pdfioObjGetType()' - Get an object's type.
|
||||
//
|
||||
|
||||
const char *pdfioObjGetType(pdfio_obj_t *obj)
|
||||
const char * // O - Object type
|
||||
pdfioObjGetType(pdfio_obj_t *obj) // I - Object
|
||||
{
|
||||
// TODO: Implement me
|
||||
(void)obj;
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -102,4 +117,8 @@ const char *pdfioObjGetType(pdfio_obj_t *obj)
|
||||
pdfio_stream_t * // O - Stream or `NULL` on error
|
||||
pdfioObjOpenStream(pdfio_obj_t *obj) // I - Object
|
||||
{
|
||||
// TODO: Implement me
|
||||
(void)obj;
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
11
pdfio-page.c
11
pdfio-page.c
@ -15,9 +15,16 @@
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// 'pdfioPageCopy()' - Copy a page to a PDF file.
|
||||
//
|
||||
|
||||
pdfio_obj_t *pdfioPageCopy(pdfio_t *pdf, pdfio_obj_t *src)
|
||||
pdfio_obj_t * // O - Destination page
|
||||
pdfioPageCopy(pdfio_file_t *pdf, // I - PDF file
|
||||
pdfio_obj_t *src) // I - Source page
|
||||
{
|
||||
// TODO: Implement me
|
||||
(void)pdf;
|
||||
(void)src;
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -56,10 +56,60 @@
|
||||
// Types and constants...
|
||||
//
|
||||
|
||||
typedef enum _pdfio_mode_e // Read/write mode
|
||||
{
|
||||
_PDFIO_MODE_READ, // Read a PDF file
|
||||
_PDFIO_MODE_WRITE // Write a PDF file
|
||||
} _pdfio_mode_t;
|
||||
|
||||
typedef struct _pdfio_value_s // Value structure
|
||||
{
|
||||
pdfio_valtype_t type; // Type of value
|
||||
union
|
||||
{
|
||||
pdfio_array_t *array; // Array value
|
||||
struct
|
||||
{
|
||||
unsigned char *data; // Data
|
||||
size_t datalen; // Length
|
||||
} binary; // Binary ("Hex String") data
|
||||
bool boolean; // Boolean value
|
||||
time_t date; // Date/time value
|
||||
pdfio_dict_t *dict; // Dictionary value
|
||||
pdfio_obj_t *obj; // Indirect object (N G obj) value
|
||||
const char *name; // Name value
|
||||
float number; // Number value
|
||||
const char *string; // String value
|
||||
} value; // Value union
|
||||
} _pdfio_value_t;
|
||||
|
||||
struct _pdfio_array_s
|
||||
{
|
||||
pdfio_file_t *pdf; // PDF file
|
||||
size_t num_values, // Number of values in use
|
||||
alloc_values; // Number of allocated values
|
||||
_pdfio_value_t *values; // Array of values
|
||||
};
|
||||
|
||||
typedef struct _pdfio_pair_s // Key/value pair
|
||||
{
|
||||
const char *key; // Key string
|
||||
_pdfio_value_t value; // Value
|
||||
} _pdfio_pair_t;
|
||||
|
||||
struct _pdfio_dict_s
|
||||
{
|
||||
pdfio_file_t *pdf; // PDF file
|
||||
size_t num_pairs, // Number of pairs in use
|
||||
alloc_pairs; // Number of allocated pairs
|
||||
_pdfio_pair_t *pairs; // Array of pairs
|
||||
};
|
||||
|
||||
struct _pdfio_file_s // PDF file structure
|
||||
{
|
||||
const char *filename; // Filename
|
||||
pdfio_mode_t mode; // Read/write mode
|
||||
char *filename; // Filename
|
||||
char *version; // Version number
|
||||
_pdfio_mode_t mode; // Read/write mode
|
||||
pdfio_error_cb_t error_cb; // Error callback
|
||||
void *error_data; // Data for error callback
|
||||
|
||||
@ -80,6 +130,9 @@ struct _pdfio_file_s // PDF file structure
|
||||
size_t num_objs, // Number of objects
|
||||
alloc_objs; // Allocated objects
|
||||
pdfio_obj_t **objs; // Objects
|
||||
size_t num_pages, // Number of pages
|
||||
alloc_pages; // Allocated pages
|
||||
pdfio_obj_t **pages; // Pages
|
||||
size_t num_strings, // Number of strings
|
||||
alloc_strings; // Allocated strings
|
||||
char **strings; // Nul-terminated strings
|
||||
@ -88,10 +141,10 @@ struct _pdfio_file_s // PDF file structure
|
||||
struct _pdfio_obj_s // Object
|
||||
{
|
||||
pdfio_file_t *pdf; // PDF file
|
||||
int number, // Number
|
||||
size_t number, // Number
|
||||
generation; // Generation
|
||||
off_t dict_offset, // Offset to dict in file
|
||||
length_offset, // Offset to /Length in dict
|
||||
off_t offset, // Offset to object in file
|
||||
length_offset, // Offset to /Length in object dict
|
||||
stream_offset; // Offset to start of stream in file
|
||||
size_t stream_length; // Length of stream, if any
|
||||
pdfio_dict_t *dict; // Dictionary
|
||||
@ -108,22 +161,6 @@ struct _pdfio_stream_s // Stream
|
||||
z_stream flate; // Flate filter state
|
||||
};
|
||||
|
||||
typedef struct _pdfio_value_s // Value structure
|
||||
{
|
||||
pdfio_valtype_t type; // Type of value
|
||||
union
|
||||
{
|
||||
pdfio_array_t *array; // Array value
|
||||
bool boolean; // Boolean value
|
||||
time_t date; // Date/time value
|
||||
pdfio_dict_t *dict; // Dictionary value
|
||||
pdfio_obj_t *obj; // Indirect object (N G obj) value
|
||||
const char *name; // Name value
|
||||
float number; // Number value
|
||||
const char *string; // String value
|
||||
} value; // Value union
|
||||
} _pdfio_value_t;
|
||||
|
||||
|
||||
//
|
||||
// Functions...
|
||||
@ -131,15 +168,19 @@ typedef struct _pdfio_value_s // Value structure
|
||||
|
||||
extern void _pdfioArrayDelete(pdfio_array_t *a) PDFIO_INTERNAL;
|
||||
extern _pdfio_value_t *_pdfioArrayGetValue(pdfio_array_t *a, size_t n) PDFIO_INTERNAL;
|
||||
extern bool _pdfioArrayWrite(pdfio_array_t *a) PDFIO_INTERNAL;
|
||||
|
||||
extern void _pdfioDictDelete(pdfio_dict_t *dict) PDFIO_INTERNAL;
|
||||
extern _pdfio_value_t *_pdfioDictGetValue(pdfio_dict_t *dict, const char *key) PDFIO_INTERNAL;
|
||||
extern bool _pdfioDictSetValue(pdfio_dict_t *dict, const char *key, _pdfio_value_t *value) PDFIO_INTERNAL;
|
||||
extern bool _pdfioDictWrite(pdfio_dict_t *dict, off_t *length) PDFIO_INTERNAL;
|
||||
|
||||
extern bool _pdfioFileDefaultError(pdfio_file_t *pdf, const char *message, void *data) PDFIO_INTERNAL;
|
||||
extern void _pdfioFileDelete(pdfio_file_t *pdf) PDFIO_INTERNAL;
|
||||
extern bool _pdfioFileError(pdfio_file_t *pdf, const char *format, ...) PDFIO_FORMAT(2,3) PDFIO_INTERNAL;
|
||||
extern bool _pdfioFileFlush(pdfio_file_t *pdf) PDFIO_INTERNAL;
|
||||
extern int _pdfioFileGetChar(pdfio_file_t *pdf) PDFIO_INTERNAL;
|
||||
extern bool _pdfioFilePrintf(pdfio_file_t *pdf, const char *format, ...) PDFIO_FORMAT(2,3) PDFIO_INTERNAL;
|
||||
extern bool _pdfioFilePuts(pdfio_file_t *pdf, const char *s) PDFIO_INTERNAL;
|
||||
extern ssize_t _pdfioFileRead(pdfio_file_t *pdf, char *buffer, size_t bytes) PDFIO_INTERNAL;
|
||||
extern off_t _pdfioFileSeek(pdfio_file_t *pdf, off_t offset, int whence) PDFIO_INTERNAL;
|
||||
extern off_t _pdfioFileTell(pdfio_file_t *pdf) PDFIO_INTERNAL;
|
||||
@ -151,7 +192,8 @@ extern void _pdfioStreamDelete(pdfio_stream_t *obj) PDFIO_INTERNAL;
|
||||
|
||||
extern bool _pdfioStringIsAllocated(pdfio_file_t *pdf, const char *s) PDFIO_INTERNAL;
|
||||
|
||||
extern _pdfio_value_t *_pdfioValueCopy(pdfio_file_t *pdfdst, _pdfio_value_t *vdst, pdfio_file_t *pdfsrc, _pdfio_value_t *vsrc) PDFIO_INTERNAL;
|
||||
extern void _pdfioValueDelete(_pdfio_value_t *v) PDFIO_INTERNAL;
|
||||
|
||||
extern bool _pdfioValueWrite(pdfio_file_t *pdf, _pdfio_value_t *v) PDFIO_INTERNAL;
|
||||
|
||||
#endif // !PDFIO_PRIVATE_H
|
||||
|
119
pdfio-value.c
119
pdfio-value.c
@ -15,11 +15,126 @@
|
||||
|
||||
|
||||
//
|
||||
// '()' - .
|
||||
// '_pdfioValueCopy()' - Copy a value to a PDF file.
|
||||
//
|
||||
|
||||
void _pdfioValueDelete(pdfio_value_t *v)
|
||||
_pdfio_value_t *
|
||||
_pdfioValueCopy(pdfio_file_t *pdfdst, // I - Destination PDF file
|
||||
_pdfio_value_t *vdst, // I - Destination value
|
||||
pdfio_file_t *pdfsrc, // I - Source PDF file
|
||||
_pdfio_value_t *vsrc) // I - Source value
|
||||
{
|
||||
// TODO: Implement me
|
||||
(void)pdfdst;
|
||||
(void)vdst;
|
||||
(void)pdfsrc;
|
||||
(void)vsrc;
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '_pdfioValueDelete()' - Free the memory used by a value.
|
||||
//
|
||||
|
||||
void
|
||||
_pdfioValueDelete(_pdfio_value_t *v) // I - Value
|
||||
{
|
||||
// TODO: Implement me
|
||||
(void)v;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '_pdfioValueWrite()' - Write a value to a PDF file.
|
||||
//
|
||||
|
||||
bool // O - `true` on success, `false` on failure
|
||||
_pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
_pdfio_value_t *v) // I - Value
|
||||
{
|
||||
switch (v->type)
|
||||
{
|
||||
default :
|
||||
return (false);
|
||||
|
||||
case PDFIO_VALTYPE_ARRAY :
|
||||
return (_pdfioArrayWrite(v->value.array));
|
||||
|
||||
case PDFIO_VALTYPE_BINARY :
|
||||
// TODO: Implement binary value support
|
||||
return (false);
|
||||
case PDFIO_VALTYPE_BOOLEAN :
|
||||
if (v->value.boolean)
|
||||
return (_pdfioFilePuts(pdf, " true"));
|
||||
else
|
||||
return (_pdfioFilePuts(pdf, " false"));
|
||||
|
||||
case PDFIO_VALTYPE_DATE :
|
||||
// TODO: Implement date value support
|
||||
break;
|
||||
|
||||
case PDFIO_VALTYPE_DICT :
|
||||
return (_pdfioDictWrite(v->value.dict, NULL));
|
||||
|
||||
case PDFIO_VALTYPE_INDIRECT :
|
||||
return (_pdfioFilePrintf(pdf, " %lu %lu obj", (unsigned long)v->value.obj->number, (unsigned long)v->value.obj->generation));
|
||||
|
||||
case PDFIO_VALTYPE_NAME :
|
||||
return (_pdfioFilePrintf(pdf, "/%s", v->value.name));
|
||||
|
||||
case PDFIO_VALTYPE_NULL :
|
||||
return (_pdfioFilePuts(pdf, " null"));
|
||||
|
||||
case PDFIO_VALTYPE_NUMBER :
|
||||
return (_pdfioFilePrintf(pdf, " %g", v->value.number));
|
||||
|
||||
case PDFIO_VALTYPE_STRING :
|
||||
{
|
||||
const char *start, // Start of fragment
|
||||
*end; // End of fragment
|
||||
|
||||
if (!_pdfioFilePuts(pdf, "("))
|
||||
return (false);
|
||||
|
||||
// Write a quoted string value...
|
||||
for (start = v->value.string; *start; start = end)
|
||||
{
|
||||
// Find the next character that needs to be quoted...
|
||||
for (end = start; *end; end ++)
|
||||
{
|
||||
if (*end == '\\' || *end == ')' || (*end & 255) < ' ')
|
||||
break;
|
||||
}
|
||||
|
||||
if (end > start)
|
||||
{
|
||||
// Write unquoted (safe) characters...
|
||||
if (!_pdfioFileWrite(pdf, start, (size_t)(end - start)))
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (*end)
|
||||
{
|
||||
// Quote this character...
|
||||
bool success; // Did the write work?
|
||||
|
||||
if (*end == '\\' || *end == ')')
|
||||
success = _pdfioFilePrintf(pdf, "\\%c", *end);
|
||||
else
|
||||
success = _pdfioFilePrintf(pdf, "\\%03o", *end);
|
||||
|
||||
if (!success)
|
||||
return (false);
|
||||
|
||||
end ++;
|
||||
}
|
||||
}
|
||||
|
||||
return (_pdfioFilePuts(pdf, ")"));
|
||||
}
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
30
pdfio.h
30
pdfio.h
@ -60,11 +60,6 @@ typedef enum pdfio_filter_e // Compression/decompression filters for streams
|
||||
PDFIO_FILTER_NONE, // No filter
|
||||
PDFIO_FILTER_FLATE // Flate filter
|
||||
} pdfio_filter_t;
|
||||
typedef enum pdfio_mode_e // Read/write mode
|
||||
{
|
||||
PDFIO_MODE_READ, // Read a PDF file
|
||||
PDFIO_MODE_WRITE // Write a PDF file
|
||||
} pdfio_mode_t;
|
||||
typedef struct _pdfio_obj_s pdfio_obj_t;// Numbered object in PDF file
|
||||
typedef struct pdfio_rect_s // PDF rectangle
|
||||
{
|
||||
@ -79,6 +74,7 @@ typedef enum pdfio_valtype_e // PDF value types
|
||||
{
|
||||
PDFIO_VALTYPE_NONE, // No value, not set
|
||||
PDFIO_VALTYPE_ARRAY, // Array
|
||||
PDFIO_VALTYPE_BINARY, // Binary data
|
||||
PDFIO_VALTYPE_BOOLEAN, // Boolean
|
||||
PDFIO_VALTYPE_DATE, // Date/time
|
||||
PDFIO_VALTYPE_DICT, // Dictionary
|
||||
@ -103,7 +99,8 @@ extern bool pdfioArrayAppendName(pdfio_array_t *a, const char *value) PDFIO_PUB
|
||||
extern bool pdfioArrayAppendNumber(pdfio_array_t *a, float value) PDFIO_PUBLIC;
|
||||
extern bool pdfioArrayAppendObject(pdfio_array_t *a, pdfio_obj_t *value) PDFIO_PUBLIC;
|
||||
extern bool pdfioArrayAppendString(pdfio_array_t *a, const char *value) PDFIO_PUBLIC;
|
||||
extern pdfio_array_t *pdfioArrayCreate(pdfio_file_t *file) PDFIO_PUBLIC;
|
||||
extern pdfio_array_t *pdfioArrayCopy(pdfio_file_t *pdf, pdfio_array_t *a) PDFIO_PUBLIC;
|
||||
extern pdfio_array_t *pdfioArrayCreate(pdfio_file_t *pdf) PDFIO_PUBLIC;
|
||||
extern pdfio_array_t *pdfioArrayGetArray(pdfio_array_t *a, size_t n) PDFIO_PUBLIC;
|
||||
extern bool pdfioArrayGetBoolean(pdfio_array_t *a, size_t n) PDFIO_PUBLIC;
|
||||
extern pdfio_dict_t *pdfioArrayGetDict(pdfio_array_t *a, size_t n) PDFIO_PUBLIC;
|
||||
@ -114,7 +111,8 @@ extern size_t pdfioArrayGetSize(pdfio_array_t *a) PDFIO_PUBLIC;
|
||||
extern const char *pdfioArrayGetString(pdfio_array_t *a, size_t n) PDFIO_PUBLIC;
|
||||
extern pdfio_valtype_t pdfioArrayGetType(pdfio_array_t *a, size_t n) PDFIO_PUBLIC;
|
||||
|
||||
extern pdfio_dict_t *pdfioDictCreate(pdfio_file_t *file) PDFIO_PUBLIC;
|
||||
extern pdfio_dict_t *pdfioDictCopy(pdfio_file_t *pdf, pdfio_dict_t *dict) PDFIO_PUBLIC;
|
||||
extern pdfio_dict_t *pdfioDictCreate(pdfio_file_t *pdf) PDFIO_PUBLIC;
|
||||
extern pdfio_array_t *pdfioDictGetArray(pdfio_dict_t *dict, const char *name) PDFIO_PUBLIC;
|
||||
extern bool pdfioDictGetBoolean(pdfio_dict_t *dict, const char *name) PDFIO_PUBLIC;
|
||||
extern pdfio_dict_t *pdfioDictGetDict(pdfio_dict_t *dict, const char *name) PDFIO_PUBLIC;
|
||||
@ -136,20 +134,22 @@ extern bool pdfioDictSetString(pdfio_dict_t *dict, const char *name, const char
|
||||
extern bool pdfioDictSetStringf(pdfio_dict_t *dict, const char *name, const char *format, ...) PDFIO_PUBLIC PDFIO_FORMAT(3,4);
|
||||
|
||||
extern bool pdfioFileClose(pdfio_file_t *pdf) PDFIO_PUBLIC;
|
||||
extern pdfio_obj_t *pdfioFileCreateObject(pdfio_file_t *file, pdfio_dict_t *dict) PDFIO_PUBLIC;
|
||||
extern pdfio_file_t *pdfioFileCreate(const char *filename, const char *version, pdfio_error_cb_t error_cb, void *error_data) PDFIO_PUBLIC;
|
||||
extern pdfio_obj_t *pdfioFileCreateObject(pdfio_file_t *pdf, pdfio_dict_t *dict) PDFIO_PUBLIC;
|
||||
extern pdfio_obj_t *pdfioFileCreatePage(pdfio_file_t *pdf, pdfio_dict_t *dict) PDFIO_PUBLIC;
|
||||
extern const char *pdfioFileGetName(pdfio_file_t *pdf) PDFIO_PUBLIC;
|
||||
extern unsigned pdfioFileGetNumObjects(pdfio_file_t *pdf) PDFIO_PUBLIC;
|
||||
extern unsigned pdfioFileGetNumPages(pdfio_file_t *pdf) PDFIO_PUBLIC;
|
||||
extern pdfio_obj_t *pdfioFileGetObject(pdfio_file_t *pdf, unsigned number) PDFIO_PUBLIC;
|
||||
extern pdfio_obj_t *pdfioFileGetPage(pdfio_file_t *pdf, unsigned number) PDFIO_PUBLIC;
|
||||
extern pdfio_file_t *pdfioFileOpen(const char *filename, pdfio_mode_t mode, pdfio_error_cb_t error_cb, void *error_data) PDFIO_PUBLIC;
|
||||
extern size_t pdfioFileGetNumObjects(pdfio_file_t *pdf) PDFIO_PUBLIC;
|
||||
extern size_t pdfioFileGetNumPages(pdfio_file_t *pdf) PDFIO_PUBLIC;
|
||||
extern pdfio_obj_t *pdfioFileGetObject(pdfio_file_t *pdf, size_t number) PDFIO_PUBLIC;
|
||||
extern pdfio_obj_t *pdfioFileGetPage(pdfio_file_t *pdf, size_t number) PDFIO_PUBLIC;
|
||||
extern const char *pdfioFileGetVersion(pdfio_file_t *pdf) PDFIO_PUBLIC;
|
||||
extern pdfio_file_t *pdfioFileOpen(const char *filename, pdfio_error_cb_t error_cb, void *error_data) PDFIO_PUBLIC;
|
||||
|
||||
extern bool pdfioObjClose(pdfio_obj_t *obj) PDFIO_PUBLIC;
|
||||
extern pdfio_stream_t *pdfioObjCreateStream(pdfio_obj_t *obj, pdfio_filter_t compression) PDFIO_PUBLIC;
|
||||
extern pdfio_dict_t *pdfioObjGetDict(pdfio_obj_t *obj) PDFIO_PUBLIC;
|
||||
extern unsigned pdfioObjGetGeneration(pdfio_obj_t *obj) PDFIO_PUBLIC;
|
||||
extern unsigned pdfioObjGetNumber(pdfio_obj_t *obj) PDFIO_PUBLIC;
|
||||
extern size_t pdfioObjGetGeneration(pdfio_obj_t *obj) PDFIO_PUBLIC;
|
||||
extern size_t pdfioObjGetNumber(pdfio_obj_t *obj) PDFIO_PUBLIC;
|
||||
extern const char *pdfioObjGetType(pdfio_obj_t *obj) PDFIO_PUBLIC;
|
||||
extern pdfio_stream_t *pdfioObjOpenStream(pdfio_obj_t *obj) PDFIO_PUBLIC;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user