mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2025-04-19 23:16:48 +02:00
Implement object mapping framework.
This commit is contained in:
parent
7cb4d0a557
commit
17f2cc213e
97
pdfio-file.c
97
pdfio-file.c
@ -22,6 +22,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
static pdfio_obj_t *add_obj(pdfio_file_t *pdf, size_t number, unsigned short generation, off_t offset);
|
static pdfio_obj_t *add_obj(pdfio_file_t *pdf, size_t number, unsigned short generation, off_t offset);
|
||||||
|
static int compare_objmaps(_pdfio_objmap_t *a, _pdfio_objmap_t *b);
|
||||||
static int compare_objs(pdfio_obj_t **a, pdfio_obj_t **b);
|
static int compare_objs(pdfio_obj_t **a, pdfio_obj_t **b);
|
||||||
static bool load_obj_stream(pdfio_obj_t *obj);
|
static bool load_obj_stream(pdfio_obj_t *obj);
|
||||||
static bool load_pages(pdfio_file_t *pdf, pdfio_obj_t *obj);
|
static bool load_pages(pdfio_file_t *pdf, pdfio_obj_t *obj);
|
||||||
@ -29,6 +30,48 @@ static bool load_xref(pdfio_file_t *pdf, off_t xref_offset);
|
|||||||
static bool write_trailer(pdfio_file_t *pdf);
|
static bool write_trailer(pdfio_file_t *pdf);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// '_pdfioFileAddMappedObject()' - Add a mapped object.
|
||||||
|
//
|
||||||
|
|
||||||
|
bool // O - `true` on success, `false` on failure
|
||||||
|
_pdfioFileAddMappedObject(
|
||||||
|
pdfio_file_t *pdf, // I - Destination PDF file
|
||||||
|
pdfio_obj_t *dst_obj, // I - Destination object
|
||||||
|
pdfio_obj_t *src_obj) // I - Source object
|
||||||
|
{
|
||||||
|
_pdfio_objmap_t *map; // Object map
|
||||||
|
|
||||||
|
|
||||||
|
// Allocate memory as needed...
|
||||||
|
if (pdf->num_objmaps >= pdf->alloc_objmaps)
|
||||||
|
{
|
||||||
|
if ((map = realloc(pdf->objmaps, (pdf->alloc_objmaps + 16) * sizeof(_pdfio_objmap_t))) == NULL)
|
||||||
|
{
|
||||||
|
_pdfioFileError(pdf, "Unable to allocate memory for object map.");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
pdf->alloc_objmaps += 16;
|
||||||
|
pdf->objmaps = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add an object to the end...
|
||||||
|
map = pdf->objmaps + pdf->num_objmaps;
|
||||||
|
pdf->num_objmaps ++;
|
||||||
|
|
||||||
|
map->obj = dst_obj;
|
||||||
|
map->src_pdf = src_obj->pdf;
|
||||||
|
map->src_number = src_obj->number;
|
||||||
|
|
||||||
|
// Sort as needed...
|
||||||
|
if (pdf->num_objmaps > 1 && compare_objmaps(map, pdf->objmaps + pdf->num_objmaps - 2) < 0)
|
||||||
|
qsort(pdf->objmaps, pdf->num_objmaps, sizeof(_pdfio_objmap_t), (int (*)(const void *, const void *))compare_objmaps);
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// 'pdfioFileClose()' - Close a PDF file and free all memory used for it.
|
// 'pdfioFileClose()' - Close a PDF file and free all memory used for it.
|
||||||
//
|
//
|
||||||
@ -67,6 +110,8 @@ pdfioFileClose(pdfio_file_t *pdf) // I - PDF file
|
|||||||
_pdfioObjDelete(pdf->objs[i]);
|
_pdfioObjDelete(pdf->objs[i]);
|
||||||
free(pdf->objs);
|
free(pdf->objs);
|
||||||
|
|
||||||
|
free(pdf->objmaps);
|
||||||
|
|
||||||
free(pdf->pages);
|
free(pdf->pages);
|
||||||
|
|
||||||
for (i = 0; i < pdf->num_strings; i ++)
|
for (i = 0; i < pdf->num_strings; i ++)
|
||||||
@ -225,6 +270,35 @@ pdfioFileCreatePage(pdfio_file_t *pdf, // I - PDF file
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// '_pdfioFileFindMappedObject()' - Find a mapped object.
|
||||||
|
//
|
||||||
|
|
||||||
|
pdfio_obj_t * // O - Match object or `NULL` if none
|
||||||
|
_pdfioFileFindMappedObject(
|
||||||
|
pdfio_file_t *pdf, // I - Destination PDF file
|
||||||
|
pdfio_file_t *src_pdf, // I - Source PDF file
|
||||||
|
size_t src_number) // I - Source object number
|
||||||
|
{
|
||||||
|
_pdfio_objmap_t key, // Search key
|
||||||
|
*match; // Matching object map
|
||||||
|
|
||||||
|
|
||||||
|
// If we have no mapped objects, return NULL immediately...
|
||||||
|
if (pdf->num_objmaps == 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
// Otherwise search for a match...
|
||||||
|
key.src_pdf = src_pdf;
|
||||||
|
key.src_number = src_number;
|
||||||
|
|
||||||
|
if ((match = (_pdfio_objmap_t *)bsearch(&key, pdf->objmaps, pdf->num_objmaps, sizeof(_pdfio_objmap_t), (int (*)(const void *, const void *))compare_objmaps)) != NULL)
|
||||||
|
return (match->obj);
|
||||||
|
else
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// 'pdfioFileFindObject()' - Find an object using its object number.
|
// 'pdfioFileFindObject()' - Find an object using its object number.
|
||||||
//
|
//
|
||||||
@ -493,11 +567,32 @@ add_obj(pdfio_file_t *pdf, // I - PDF file
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 'compare_objmaps()' - Compare two object maps...
|
||||||
|
//
|
||||||
|
|
||||||
|
static int // O - Result of comparison
|
||||||
|
compare_objmaps(_pdfio_objmap_t *a, // I - First object map
|
||||||
|
_pdfio_objmap_t *b) // I - Second object map
|
||||||
|
{
|
||||||
|
if (a->src_pdf < b->src_pdf)
|
||||||
|
return (-1);
|
||||||
|
else if (a->src_pdf > b->src_pdf)
|
||||||
|
return (1);
|
||||||
|
else if (a->src_number < b->src_number)
|
||||||
|
return (-1);
|
||||||
|
else if (a->src_number > b->src_number)
|
||||||
|
return (1);
|
||||||
|
else
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// 'compare_objs()' - Compare the object numbers of two objects.
|
// 'compare_objs()' - Compare the object numbers of two objects.
|
||||||
//
|
//
|
||||||
|
|
||||||
static int
|
static int // O - Result of comparison
|
||||||
compare_objs(pdfio_obj_t **a, // I - First object
|
compare_objs(pdfio_obj_t **a, // I - First object
|
||||||
pdfio_obj_t **b) // I - Second object
|
pdfio_obj_t **b) // I - Second object
|
||||||
{
|
{
|
||||||
|
@ -135,7 +135,7 @@ typedef struct _pdfio_pair_s // Key/value pair
|
|||||||
_pdfio_value_t value; // Value
|
_pdfio_value_t value; // Value
|
||||||
} _pdfio_pair_t;
|
} _pdfio_pair_t;
|
||||||
|
|
||||||
struct _pdfio_dict_s
|
struct _pdfio_dict_s // Dictionary
|
||||||
{
|
{
|
||||||
pdfio_file_t *pdf; // PDF file
|
pdfio_file_t *pdf; // PDF file
|
||||||
size_t num_pairs, // Number of pairs in use
|
size_t num_pairs, // Number of pairs in use
|
||||||
@ -143,6 +143,13 @@ struct _pdfio_dict_s
|
|||||||
_pdfio_pair_t *pairs; // Array of pairs
|
_pdfio_pair_t *pairs; // Array of pairs
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _pdfio_objmap_s // PDF object map
|
||||||
|
{
|
||||||
|
pdfio_obj_t *obj; // Object for this file
|
||||||
|
pdfio_file_t *src_pdf; // Source PDF file
|
||||||
|
size_t src_number; // Source object number
|
||||||
|
} _pdfio_objmap_t;
|
||||||
|
|
||||||
struct _pdfio_file_s // PDF file structure
|
struct _pdfio_file_s // PDF file structure
|
||||||
{
|
{
|
||||||
char *filename; // Filename
|
char *filename; // Filename
|
||||||
@ -173,6 +180,9 @@ struct _pdfio_file_s // PDF file structure
|
|||||||
size_t num_objs, // Number of objects
|
size_t num_objs, // Number of objects
|
||||||
alloc_objs; // Allocated objects
|
alloc_objs; // Allocated objects
|
||||||
pdfio_obj_t **objs; // Objects
|
pdfio_obj_t **objs; // Objects
|
||||||
|
size_t num_objmaps, // Number of object maps
|
||||||
|
alloc_objmaps; // Allocated object maps
|
||||||
|
_pdfio_objmap_t *objmaps; // Object maps
|
||||||
size_t num_pages, // Number of pages
|
size_t num_pages, // Number of pages
|
||||||
alloc_pages; // Allocated pages
|
alloc_pages; // Allocated pages
|
||||||
pdfio_obj_t **pages; // Pages
|
pdfio_obj_t **pages; // Pages
|
||||||
@ -230,9 +240,11 @@ extern pdfio_dict_t *_pdfioDictRead(pdfio_file_t *pdf, _pdfio_token_t *ts) PDFIO
|
|||||||
extern bool _pdfioDictSetValue(pdfio_dict_t *dict, const char *key, _pdfio_value_t *value) 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 _pdfioDictWrite(pdfio_dict_t *dict, off_t *length) PDFIO_INTERNAL;
|
||||||
|
|
||||||
|
extern bool _pdfioFileAddMappedObject(pdfio_file_t *pdf, pdfio_obj_t *dst_obj, pdfio_obj_t *src_obj) PDFIO_INTERNAL;
|
||||||
extern bool _pdfioFileConsume(pdfio_file_t *pdf, size_t bytes) PDFIO_INTERNAL;
|
extern bool _pdfioFileConsume(pdfio_file_t *pdf, size_t bytes) PDFIO_INTERNAL;
|
||||||
extern bool _pdfioFileDefaultError(pdfio_file_t *pdf, const char *message, void *data) PDFIO_INTERNAL;
|
extern bool _pdfioFileDefaultError(pdfio_file_t *pdf, const char *message, void *data) PDFIO_INTERNAL;
|
||||||
extern bool _pdfioFileError(pdfio_file_t *pdf, const char *format, ...) PDFIO_FORMAT(2,3) PDFIO_INTERNAL;
|
extern bool _pdfioFileError(pdfio_file_t *pdf, const char *format, ...) PDFIO_FORMAT(2,3) PDFIO_INTERNAL;
|
||||||
|
extern pdfio_obj_t *_pdfioFileFindMappedObject(pdfio_file_t *pdf, pdfio_file_t *src_pdf, size_t src_number) PDFIO_INTERNAL;
|
||||||
extern bool _pdfioFileFlush(pdfio_file_t *pdf) PDFIO_INTERNAL;
|
extern bool _pdfioFileFlush(pdfio_file_t *pdf) PDFIO_INTERNAL;
|
||||||
extern int _pdfioFileGetChar(pdfio_file_t *pdf) PDFIO_INTERNAL;
|
extern int _pdfioFileGetChar(pdfio_file_t *pdf) PDFIO_INTERNAL;
|
||||||
extern bool _pdfioFileGets(pdfio_file_t *pdf, char *buffer, size_t bufsize) PDFIO_INTERNAL;
|
extern bool _pdfioFileGets(pdfio_file_t *pdf, char *buffer, size_t bufsize) PDFIO_INTERNAL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user