2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
2021-05-30 13:10:44 +02:00
|
|
|
|
// PDF dictionary functions for PDFio.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
2024-10-25 23:48:19 +02:00
|
|
|
|
// Copyright © 2021-2024 by Michael R Sweet.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
|
|
|
|
// information.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#include "pdfio-private.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-04-28 03:22:34 +02:00
|
|
|
|
// Local functions...
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-28 03:22:34 +02:00
|
|
|
|
static int compare_pairs(_pdfio_pair_t *a, _pdfio_pair_t *b);
|
2021-04-26 02:12:52 +02:00
|
|
|
|
|
|
|
|
|
|
2021-10-26 03:22:59 +02:00
|
|
|
|
//
|
2024-10-25 23:48:19 +02:00
|
|
|
|
// 'pdfioDictClear()' - Remove a key/value pair from a dictionary.
|
2021-10-26 03:22:59 +02:00
|
|
|
|
//
|
|
|
|
|
|
2024-10-25 23:48:19 +02:00
|
|
|
|
bool // O - `true` if cleared, `false` otherwise
|
|
|
|
|
pdfioDictClear(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key) // I - Key
|
2021-10-26 03:22:59 +02:00
|
|
|
|
{
|
|
|
|
|
size_t idx; // Index into pairs
|
|
|
|
|
_pdfio_pair_t *pair, // Current pair
|
|
|
|
|
pkey; // Search key
|
|
|
|
|
|
|
|
|
|
|
2024-10-25 23:48:19 +02:00
|
|
|
|
PDFIO_DEBUG("pdfioDictClear(dict=%p, key=\"%s\")\n", dict, key);
|
|
|
|
|
|
|
|
|
|
if (!dict || !key)
|
|
|
|
|
return (false);
|
2021-10-26 03:22:59 +02:00
|
|
|
|
|
|
|
|
|
// See if the key is already set...
|
|
|
|
|
if (dict->num_pairs > 0)
|
|
|
|
|
{
|
|
|
|
|
pkey.key = key;
|
|
|
|
|
|
|
|
|
|
if ((pair = (_pdfio_pair_t *)bsearch(&pkey, dict->pairs, dict->num_pairs, sizeof(_pdfio_pair_t), (int (*)(const void *, const void *))compare_pairs)) != NULL)
|
|
|
|
|
{
|
|
|
|
|
// Yes, remove it...
|
2021-10-31 13:30:08 +01:00
|
|
|
|
if (pair->value.type == PDFIO_VALTYPE_BINARY)
|
|
|
|
|
free(pair->value.value.binary.data);
|
|
|
|
|
|
2021-10-26 03:22:59 +02:00
|
|
|
|
idx = (size_t)(pair - dict->pairs);
|
|
|
|
|
dict->num_pairs --;
|
|
|
|
|
|
|
|
|
|
if (idx < dict->num_pairs)
|
|
|
|
|
memmove(pair, pair + 1, (dict->num_pairs - idx) * sizeof(_pdfio_pair_t));
|
2024-10-25 23:48:19 +02:00
|
|
|
|
|
|
|
|
|
return (true);
|
2021-10-26 03:22:59 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-25 23:48:19 +02:00
|
|
|
|
|
|
|
|
|
return (false);
|
2021-10-26 03:22:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
//
|
2021-04-28 03:22:34 +02:00
|
|
|
|
// 'pdfioDictCopy()' - Copy a dictionary to a PDF file.
|
2021-04-26 02:12:52 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-28 03:22:34 +02:00
|
|
|
|
pdfio_dict_t * // O - New dictionary
|
|
|
|
|
pdfioDictCopy(pdfio_file_t *pdf, // I - PDF file
|
|
|
|
|
pdfio_dict_t *dict) // I - Original dictionary
|
|
|
|
|
{
|
2021-04-30 14:21:21 +02:00
|
|
|
|
pdfio_dict_t *ndict; // New dictionary
|
|
|
|
|
size_t i; // Looping var
|
|
|
|
|
_pdfio_pair_t *p; // Current source pair
|
|
|
|
|
const char *key; // Current destination key
|
|
|
|
|
_pdfio_value_t v; // Current destination value
|
|
|
|
|
|
|
|
|
|
|
2021-05-30 02:00:48 +02:00
|
|
|
|
PDFIO_DEBUG("pdfioDictCopy(pdf=%p, dict=%p(%p))\n", pdf, dict, dict ? dict->pdf : NULL);
|
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
// Create the new dictionary...
|
|
|
|
|
if ((ndict = pdfioDictCreate(pdf)) == NULL)
|
|
|
|
|
return (NULL);
|
|
|
|
|
|
|
|
|
|
// Pre-allocate the pairs array to make this a little faster...
|
|
|
|
|
if ((ndict->pairs = (_pdfio_pair_t *)malloc(dict->num_pairs * sizeof(_pdfio_pair_t))) == NULL)
|
|
|
|
|
return (NULL); // Let pdfioFileClose do the cleanup...
|
|
|
|
|
|
|
|
|
|
ndict->alloc_pairs = dict->num_pairs;
|
|
|
|
|
|
|
|
|
|
// Copy and add each of the source dictionary's key/value pairs...
|
|
|
|
|
for (i = dict->num_pairs, p = dict->pairs; i > 0; i --, p ++)
|
|
|
|
|
{
|
2021-05-30 02:00:48 +02:00
|
|
|
|
if (!strcmp(p->key, "Length") && p->value.type == PDFIO_VALTYPE_INDIRECT && dict->pdf != pdf)
|
|
|
|
|
{
|
|
|
|
|
// Don't use indirect stream lengths for copied objects...
|
2021-06-07 14:34:30 +02:00
|
|
|
|
pdfio_obj_t *lenobj = pdfioFileFindObj(dict->pdf, p->value.value.indirect.number);
|
2021-05-30 02:00:48 +02:00
|
|
|
|
// Length object
|
|
|
|
|
|
|
|
|
|
v.type = PDFIO_VALTYPE_NUMBER;
|
|
|
|
|
if (lenobj)
|
|
|
|
|
{
|
|
|
|
|
if (lenobj->value.type == PDFIO_VALTYPE_NONE)
|
|
|
|
|
_pdfioObjLoad(lenobj);
|
|
|
|
|
|
|
|
|
|
v.value.number = lenobj->value.value.number;
|
|
|
|
|
}
|
|
|
|
|
else
|
2021-05-30 03:16:21 +02:00
|
|
|
|
v.value.number = 0.0;
|
2021-05-30 02:00:48 +02:00
|
|
|
|
}
|
|
|
|
|
else if (!_pdfioValueCopy(pdf, &v, dict->pdf, &p->value))
|
2021-04-30 14:21:21 +02:00
|
|
|
|
return (NULL); // Let pdfioFileClose do the cleanup...
|
|
|
|
|
|
|
|
|
|
if (_pdfioStringIsAllocated(dict->pdf, p->key))
|
|
|
|
|
key = pdfioStringCreate(pdf, p->key);
|
|
|
|
|
else
|
|
|
|
|
key = p->key;
|
|
|
|
|
|
|
|
|
|
if (!key)
|
|
|
|
|
return (NULL); // Let pdfioFileClose do the cleanup...
|
|
|
|
|
|
|
|
|
|
// Cannot fail since we already allocated space for the pairs...
|
|
|
|
|
_pdfioDictSetValue(ndict, key, &v);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Successfully copied the dictionary, so return it...
|
|
|
|
|
return (ndict);
|
2021-04-28 03:22:34 +02:00
|
|
|
|
}
|
2021-04-26 02:12:52 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'pdfioDictCreate()' - Create a dictionary to hold key/value pairs.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
pdfio_dict_t * // O - New dictionary
|
|
|
|
|
pdfioDictCreate(pdfio_file_t *pdf) // I - PDF file
|
|
|
|
|
{
|
|
|
|
|
pdfio_dict_t *dict; // New dictionary
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!pdf)
|
|
|
|
|
return (NULL);
|
|
|
|
|
|
|
|
|
|
if ((dict = (pdfio_dict_t *)calloc(1, sizeof(pdfio_dict_t))) == NULL)
|
|
|
|
|
return (NULL);
|
|
|
|
|
|
|
|
|
|
dict->pdf = pdf;
|
|
|
|
|
|
|
|
|
|
if (pdf->num_dicts >= pdf->alloc_dicts)
|
|
|
|
|
{
|
|
|
|
|
pdfio_dict_t **temp = (pdfio_dict_t **)realloc(pdf->dicts, (pdf->alloc_dicts + 16) * sizeof(pdfio_dict_t *));
|
|
|
|
|
|
|
|
|
|
if (!temp)
|
|
|
|
|
{
|
|
|
|
|
free(dict);
|
|
|
|
|
return (NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pdf->dicts = temp;
|
|
|
|
|
pdf->alloc_dicts += 16;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pdf->dicts[pdf->num_dicts ++] = dict;
|
|
|
|
|
|
|
|
|
|
return (dict);
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-12-14 22:02:26 +01:00
|
|
|
|
//
|
|
|
|
|
// '_pdfioDictDecrypt()' - Decrypt the values in a dictionary.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
bool // O - `true` on success, `false` on error
|
|
|
|
|
_pdfioDictDecrypt(pdfio_file_t *pdf, // I - PDF file
|
|
|
|
|
pdfio_obj_t *obj, // I - Object
|
|
|
|
|
pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
size_t depth) // I - Depth
|
|
|
|
|
{
|
|
|
|
|
size_t i; // Looping var
|
|
|
|
|
_pdfio_pair_t *pair; // Current pair
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = dict->num_pairs, pair = dict->pairs; i > 0; i --, pair ++)
|
|
|
|
|
{
|
|
|
|
|
if (strcmp(pair->key, "ID") && !_pdfioValueDecrypt(pdf, obj, &pair->value, depth + 1))
|
|
|
|
|
return (false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-05-04 18:59:10 +02:00
|
|
|
|
//
|
|
|
|
|
// '_pdfioDictDebug()' - Dump a dictionary to stderr.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
void
|
2021-05-10 14:40:52 +02:00
|
|
|
|
_pdfioDictDebug(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
FILE *fp) // I - Output file
|
2021-05-04 18:59:10 +02:00
|
|
|
|
{
|
|
|
|
|
size_t i; // Looping var
|
|
|
|
|
_pdfio_pair_t *pair; // Current pair
|
|
|
|
|
|
|
|
|
|
|
2024-08-21 15:22:58 +02:00
|
|
|
|
if (!dict)
|
|
|
|
|
return;
|
|
|
|
|
|
2021-05-04 18:59:10 +02:00
|
|
|
|
for (i = dict->num_pairs, pair = dict->pairs; i > 0; i --, pair ++)
|
|
|
|
|
{
|
2021-05-10 14:40:52 +02:00
|
|
|
|
fprintf(fp, "/%s", pair->key);
|
|
|
|
|
_pdfioValueDebug(&pair->value, fp);
|
2021-05-04 18:59:10 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-17 03:09:43 +02:00
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// '_pdfioDictDelete()' - Free the memory used by a dictionary.
|
2021-04-17 03:09:43 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
void
|
|
|
|
|
_pdfioDictDelete(pdfio_dict_t *dict) // I - Dictionary
|
2021-04-17 03:09:43 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
if (dict)
|
2021-10-31 13:30:08 +01:00
|
|
|
|
{
|
|
|
|
|
size_t i; // Looping var
|
|
|
|
|
_pdfio_pair_t *pair; // Current pair
|
|
|
|
|
|
|
|
|
|
for (i = dict->num_pairs, pair = dict->pairs; i > 0; i --, pair ++)
|
|
|
|
|
{
|
|
|
|
|
if (pair->value.type == PDFIO_VALTYPE_BINARY)
|
|
|
|
|
free(pair->value.value.binary.data);
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
free(dict->pairs);
|
2021-10-31 13:30:08 +01:00
|
|
|
|
}
|
2021-04-26 02:12:52 +02:00
|
|
|
|
|
|
|
|
|
free(dict);
|
2021-04-17 03:09:43 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictGetArray()' - Get a key array value from a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
pdfio_array_t * // O - Value
|
|
|
|
|
pdfioDictGetArray(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key) // I - Key
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t *value = _pdfioDictGetValue(dict, key);
|
|
|
|
|
|
2021-07-08 04:06:25 +02:00
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
if (value && value->type == PDFIO_VALTYPE_ARRAY)
|
|
|
|
|
return (value->value.array);
|
|
|
|
|
else
|
|
|
|
|
return (NULL);
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
//
|
|
|
|
|
// 'pdfioDictGetBinary()' - Get a key binary string value from a dictionary.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
unsigned char * // O - Value
|
|
|
|
|
pdfioDictGetBinary(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
|
|
|
|
size_t *length)// O - Length of value
|
|
|
|
|
{
|
|
|
|
|
_pdfio_value_t *value = _pdfioDictGetValue(dict, key);
|
|
|
|
|
|
2021-07-08 04:06:25 +02:00
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
if (!length)
|
|
|
|
|
return (NULL);
|
|
|
|
|
|
|
|
|
|
if (value && value->type == PDFIO_VALTYPE_BINARY)
|
|
|
|
|
{
|
|
|
|
|
*length = value->value.binary.datalen;
|
|
|
|
|
return (value->value.binary.data);
|
|
|
|
|
}
|
2021-11-02 02:30:46 +01:00
|
|
|
|
else if (value && value->type == PDFIO_VALTYPE_STRING)
|
|
|
|
|
{
|
|
|
|
|
*length = strlen(value->value.string);
|
|
|
|
|
return ((unsigned char *)value->value.string);
|
|
|
|
|
}
|
2021-04-30 14:21:21 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
*length = 0;
|
|
|
|
|
return (NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictGetBoolean()' - Get a key boolean value from a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
bool // O - Value
|
|
|
|
|
pdfioDictGetBoolean(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key) // I - Key
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t *value = _pdfioDictGetValue(dict, key);
|
|
|
|
|
|
2021-07-08 04:06:25 +02:00
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
if (value && value->type == PDFIO_VALTYPE_BOOLEAN)
|
|
|
|
|
return (value->value.boolean);
|
|
|
|
|
else
|
|
|
|
|
return (false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-07-08 04:06:25 +02:00
|
|
|
|
//
|
|
|
|
|
// 'pdfioDictGetDate()' - Get a date value from a dictionary.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
time_t // O - Value
|
|
|
|
|
pdfioDictGetDate(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key) // I - Key
|
|
|
|
|
{
|
|
|
|
|
_pdfio_value_t *value = _pdfioDictGetValue(dict, key);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (value && value->type == PDFIO_VALTYPE_DATE)
|
|
|
|
|
return (value->value.date);
|
|
|
|
|
else
|
|
|
|
|
return (0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
//
|
|
|
|
|
// 'pdfioDictGetDict()' - Get a key dictionary value from a dictionary.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
pdfio_dict_t * // O - Value
|
|
|
|
|
pdfioDictGetDict(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key) // I - Key
|
|
|
|
|
{
|
|
|
|
|
_pdfio_value_t *value = _pdfioDictGetValue(dict, key);
|
|
|
|
|
|
2021-07-08 04:06:25 +02:00
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
if (value && value->type == PDFIO_VALTYPE_DICT)
|
|
|
|
|
return (value->value.dict);
|
|
|
|
|
else
|
|
|
|
|
return (NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-10-25 23:48:19 +02:00
|
|
|
|
//
|
|
|
|
|
// 'pdfioDictGetKey()' - Get the key for the specified pair.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
const char * // O - Key for specified pair
|
|
|
|
|
pdfioDictGetKey(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
size_t n) // I - Pair index (`0`-based)
|
|
|
|
|
{
|
|
|
|
|
return ((dict && n < dict->num_pairs) ? dict->pairs[n].key : NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
//
|
|
|
|
|
// 'pdfioDictGetName()' - Get a key name value from a dictionary.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
const char * // O - Value
|
|
|
|
|
pdfioDictGetName(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key) // I - Key
|
|
|
|
|
{
|
|
|
|
|
_pdfio_value_t *value = _pdfioDictGetValue(dict, key);
|
|
|
|
|
|
2021-07-08 04:06:25 +02:00
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
if (value && value->type == PDFIO_VALTYPE_NAME)
|
|
|
|
|
return (value->value.name);
|
|
|
|
|
else
|
|
|
|
|
return (NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-10-25 23:48:19 +02:00
|
|
|
|
//
|
|
|
|
|
// 'pdfioDictGetNumPairs()' - Get the number of key/value pairs in a dictionary.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
size_t // O - Number of pairs
|
|
|
|
|
pdfioDictGetNumPairs(pdfio_dict_t *dict)// I - Dictionary
|
|
|
|
|
{
|
|
|
|
|
return (dict ? dict->num_pairs : 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
//
|
|
|
|
|
// 'pdfioDictGetNumber()' - Get a key number value from a dictionary.
|
|
|
|
|
//
|
|
|
|
|
|
2021-05-30 03:16:21 +02:00
|
|
|
|
double // O - Value
|
2021-04-26 02:12:52 +02:00
|
|
|
|
pdfioDictGetNumber(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key) // I - Key
|
|
|
|
|
{
|
|
|
|
|
_pdfio_value_t *value = _pdfioDictGetValue(dict, key);
|
|
|
|
|
|
2021-07-08 04:06:25 +02:00
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
if (value && value->type == PDFIO_VALTYPE_NUMBER)
|
|
|
|
|
return (value->value.number);
|
|
|
|
|
else
|
2021-05-30 03:16:21 +02:00
|
|
|
|
return (0.0);
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-06-07 14:34:30 +02:00
|
|
|
|
// 'pdfioDictGetObj()' - Get a key indirect object value from a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
pdfio_obj_t * // O - Value
|
2021-06-07 14:34:30 +02:00
|
|
|
|
pdfioDictGetObj(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key) // I - Key
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t *value = _pdfioDictGetValue(dict, key);
|
|
|
|
|
|
2021-07-08 04:06:25 +02:00
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
if (value && value->type == PDFIO_VALTYPE_INDIRECT)
|
2021-06-07 14:34:30 +02:00
|
|
|
|
return (pdfioFileFindObj(dict->pdf, value->value.indirect.number));
|
2021-04-26 02:12:52 +02:00
|
|
|
|
else
|
|
|
|
|
return (NULL);
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictGetRect()' - Get a key rectangle value from a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
pdfio_rect_t * // O - Rectangle
|
|
|
|
|
pdfioDictGetRect(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
|
|
|
|
pdfio_rect_t *rect) // I - Rectangle
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t *value = _pdfioDictGetValue(dict, key);
|
|
|
|
|
|
2021-07-08 04:06:25 +02:00
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
if (value && value->type == PDFIO_VALTYPE_ARRAY && pdfioArrayGetSize(value->value.array) == 4)
|
|
|
|
|
{
|
|
|
|
|
rect->x1 = pdfioArrayGetNumber(value->value.array, 0);
|
|
|
|
|
rect->y1 = pdfioArrayGetNumber(value->value.array, 1);
|
|
|
|
|
rect->x2 = pdfioArrayGetNumber(value->value.array, 2);
|
|
|
|
|
rect->y2 = pdfioArrayGetNumber(value->value.array, 3);
|
|
|
|
|
return (rect);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
memset(rect, 0, sizeof(pdfio_rect_t));
|
|
|
|
|
return (NULL);
|
|
|
|
|
}
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictGetString()' - Get a key string value from a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
const char * // O - Value
|
|
|
|
|
pdfioDictGetString(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key) // I - Key
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t *value = _pdfioDictGetValue(dict, key);
|
|
|
|
|
|
2021-07-08 04:06:25 +02:00
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
if (value && value->type == PDFIO_VALTYPE_STRING)
|
2024-06-24 17:46:15 +02:00
|
|
|
|
{
|
|
|
|
|
return (value->value.string);
|
|
|
|
|
}
|
|
|
|
|
else if (value && value->type == PDFIO_VALTYPE_BINARY && value->value.binary.datalen < 4096)
|
|
|
|
|
{
|
|
|
|
|
// Convert binary string to regular string...
|
|
|
|
|
char temp[4096]; // Temporary string
|
|
|
|
|
|
|
|
|
|
memcpy(temp, value->value.binary.data, value->value.binary.datalen);
|
|
|
|
|
temp[value->value.binary.datalen] = '\0';
|
|
|
|
|
|
|
|
|
|
free(value->value.binary.data);
|
|
|
|
|
value->type = PDFIO_VALTYPE_STRING;
|
|
|
|
|
value->value.string = pdfioStringCreate(dict->pdf, temp);
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
return (value->value.string);
|
2024-06-24 17:46:15 +02:00
|
|
|
|
}
|
2021-04-26 02:12:52 +02:00
|
|
|
|
else
|
2024-06-24 17:46:15 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
return (NULL);
|
2024-06-24 17:46:15 +02:00
|
|
|
|
}
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictGetType()' - Get a key value type from a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
pdfio_valtype_t // O - Value type
|
|
|
|
|
pdfioDictGetType(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key) // I - Key
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t *value = _pdfioDictGetValue(dict, key);
|
|
|
|
|
|
2021-07-08 04:06:25 +02:00
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
return (value ? value->type : PDFIO_VALTYPE_NONE);
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// '_pdfioDictGetValue()' - Get a key value from a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t * // O - Value or `NULL` on error
|
|
|
|
|
_pdfioDictGetValue(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key) // I - Key
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_pair_t temp, // Search key
|
|
|
|
|
*match; // Matching key pair
|
|
|
|
|
|
|
|
|
|
|
2021-05-08 01:51:38 +02:00
|
|
|
|
PDFIO_DEBUG("_pdfioDictGetValue(dict=%p, key=\"%s\")\n", dict, key);
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
if (!dict || !dict->num_pairs || !key)
|
2021-05-08 01:51:38 +02:00
|
|
|
|
{
|
|
|
|
|
PDFIO_DEBUG("_pdfioDictGetValue: Returning NULL.\n");
|
2021-04-26 02:12:52 +02:00
|
|
|
|
return (NULL);
|
2021-05-08 01:51:38 +02:00
|
|
|
|
}
|
2021-04-26 02:12:52 +02:00
|
|
|
|
|
|
|
|
|
temp.key = key;
|
|
|
|
|
|
|
|
|
|
if ((match = bsearch(&temp, dict->pairs, dict->num_pairs, sizeof(_pdfio_pair_t), (int (*)(const void *, const void *))compare_pairs)) != NULL)
|
2021-05-08 01:51:38 +02:00
|
|
|
|
{
|
|
|
|
|
PDFIO_DEBUG("_pdfioDictGetValue: Match, returning ");
|
|
|
|
|
PDFIO_DEBUG_VALUE(&(match->value));
|
|
|
|
|
PDFIO_DEBUG(".\n");
|
|
|
|
|
return (&(match->value));
|
|
|
|
|
}
|
2021-04-26 02:12:52 +02:00
|
|
|
|
else
|
2021-05-08 01:51:38 +02:00
|
|
|
|
{
|
|
|
|
|
PDFIO_DEBUG("_pdfioDictGetValue: No match, returning NULL.\n");
|
2021-04-26 02:12:52 +02:00
|
|
|
|
return (NULL);
|
2021-05-08 01:51:38 +02:00
|
|
|
|
}
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-06-27 16:17:00 +02:00
|
|
|
|
//
|
|
|
|
|
// 'pdfioDictIterateKeys()' - Iterate the keys in a dictionary.
|
|
|
|
|
//
|
|
|
|
|
// This function iterates the keys in a dictionary, calling the supplied
|
|
|
|
|
// function "cb":
|
|
|
|
|
//
|
|
|
|
|
// ```
|
|
|
|
|
// bool
|
|
|
|
|
// my_dict_cb(pdfio_dict_t *dict, const char *key, void *cb_data)
|
|
|
|
|
// {
|
|
|
|
|
// ... "key" contains the dictionary key ...
|
|
|
|
|
// ... return true to continue or false to stop ...
|
|
|
|
|
// }
|
|
|
|
|
// ```
|
|
|
|
|
//
|
|
|
|
|
// The iteration continues as long as the callback returns `true` or all keys
|
|
|
|
|
// have been iterated.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
pdfioDictIterateKeys(
|
|
|
|
|
pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
pdfio_dict_cb_t cb, // I - Callback function
|
|
|
|
|
void *cb_data) // I - Callback data
|
|
|
|
|
{
|
|
|
|
|
size_t i; // Looping var
|
|
|
|
|
_pdfio_pair_t *pair; // Current pair
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Range check input...
|
|
|
|
|
if (!dict || !cb)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (i = dict->num_pairs, pair = dict->pairs; i > 0; i --, pair ++)
|
|
|
|
|
{
|
|
|
|
|
if (!(cb)(dict, pair->key, cb_data))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-05-01 23:50:52 +02:00
|
|
|
|
//
|
|
|
|
|
// '_pdfioDictRead()' - Read a dictionary from a PDF file.
|
|
|
|
|
//
|
|
|
|
|
// At this point we've seen the initial "<<"...
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
pdfio_dict_t * // O - New dictionary
|
2021-05-08 13:38:44 +02:00
|
|
|
|
_pdfioDictRead(pdfio_file_t *pdf, // I - PDF file
|
2021-10-24 00:08:16 +02:00
|
|
|
|
pdfio_obj_t *obj, // I - Object, if any
|
2021-11-29 23:46:56 +01:00
|
|
|
|
_pdfio_token_t *tb, // I - Token buffer/stack
|
|
|
|
|
size_t depth) // I - Depth of dictionary
|
2021-05-01 23:50:52 +02:00
|
|
|
|
{
|
2021-05-04 16:34:17 +02:00
|
|
|
|
pdfio_dict_t *dict; // New dictionary
|
|
|
|
|
char key[256]; // Dictionary key
|
|
|
|
|
_pdfio_value_t value; // Dictionary value
|
|
|
|
|
|
|
|
|
|
|
2023-12-13 18:48:31 +01:00
|
|
|
|
PDFIO_DEBUG("_pdfioDictRead(pdf=%p, obj=%p, tb=%p, depth=%lu)\n", pdf, obj, tb, (unsigned long)depth);
|
2021-05-04 18:59:10 +02:00
|
|
|
|
|
2021-05-04 16:34:17 +02:00
|
|
|
|
// Create a dictionary and start reading...
|
2021-06-09 15:14:57 +02:00
|
|
|
|
if ((dict = pdfioDictCreate(pdf)) == NULL)
|
|
|
|
|
return (NULL);
|
2021-05-04 16:34:17 +02:00
|
|
|
|
|
2021-05-08 13:38:44 +02:00
|
|
|
|
while (_pdfioTokenGet(tb, key, sizeof(key)))
|
2021-05-04 16:34:17 +02:00
|
|
|
|
{
|
|
|
|
|
// Get the next key or end-of-dictionary...
|
|
|
|
|
if (!strcmp(key, ">>"))
|
|
|
|
|
{
|
|
|
|
|
// End of dictionary...
|
2023-12-13 18:48:31 +01:00
|
|
|
|
PDFIO_DEBUG("_pdfioDictRead: Returning dictionary value...\n");
|
2021-05-04 16:34:17 +02:00
|
|
|
|
return (dict);
|
|
|
|
|
}
|
|
|
|
|
else if (key[0] != '/')
|
|
|
|
|
{
|
|
|
|
|
_pdfioFileError(pdf, "Invalid dictionary contents.");
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-02-04 02:39:04 +01:00
|
|
|
|
else if (_pdfioDictGetValue(dict, key + 1))
|
|
|
|
|
{
|
|
|
|
|
_pdfioFileError(pdf, "Duplicate dictionary key '%s'.", key + 1);
|
|
|
|
|
return (NULL);
|
|
|
|
|
}
|
2021-05-01 23:50:52 +02:00
|
|
|
|
|
2021-05-04 16:34:17 +02:00
|
|
|
|
// Then get the next value...
|
2023-02-04 02:39:04 +01:00
|
|
|
|
PDFIO_DEBUG("_pdfioDictRead: Reading value for '%s'.\n", key + 1);
|
|
|
|
|
|
2021-11-29 23:46:56 +01:00
|
|
|
|
if (!_pdfioValueRead(pdf, obj, tb, &value, depth))
|
2021-05-04 16:34:17 +02:00
|
|
|
|
{
|
2023-12-13 18:48:31 +01:00
|
|
|
|
_pdfioFileError(pdf, "Missing value for dictionary key '%s'.", key + 1);
|
2021-05-04 16:34:17 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
2021-05-01 23:50:52 +02:00
|
|
|
|
|
2021-05-04 18:59:10 +02:00
|
|
|
|
if (!_pdfioDictSetValue(dict, pdfioStringCreate(pdf, key + 1), &value))
|
2021-05-04 16:34:17 +02:00
|
|
|
|
break;
|
2021-05-04 18:59:10 +02:00
|
|
|
|
|
2023-12-13 18:48:31 +01:00
|
|
|
|
PDFIO_DEBUG("_pdfioDictRead: Set %s.\n", key);
|
2021-05-04 16:34:17 +02:00
|
|
|
|
}
|
2021-05-01 23:50:52 +02:00
|
|
|
|
|
2021-05-04 16:34:17 +02:00
|
|
|
|
// Dictionary is invalid - pdfioFileClose will free the memory, return NULL
|
|
|
|
|
// to indicate an error...
|
2021-05-01 23:50:52 +02:00
|
|
|
|
return (NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictSetArray()' - Set a key array in a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
bool // O - `true` on success, `false` on failure
|
|
|
|
|
pdfioDictSetArray(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
|
|
|
|
pdfio_array_t *value) // I - Value
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t temp; // New value
|
|
|
|
|
|
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
// Range check input...
|
|
|
|
|
if (!dict || !key || !value)
|
|
|
|
|
return (false);
|
|
|
|
|
|
|
|
|
|
// Set the key/value pair...
|
2021-04-26 02:12:52 +02:00
|
|
|
|
temp.type = PDFIO_VALTYPE_ARRAY;
|
|
|
|
|
temp.value.array = value;
|
|
|
|
|
|
|
|
|
|
return (_pdfioDictSetValue(dict, key, &temp));
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
//
|
|
|
|
|
// 'pdfioDictSetBinary()' - Set a key binary string in a dictionary.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool // O - `true` on success, `false` on failure
|
|
|
|
|
pdfioDictSetBinary(
|
2021-06-05 17:28:32 +02:00
|
|
|
|
pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
|
|
|
|
const unsigned char *value, // I - Value
|
|
|
|
|
size_t valuelen) // I - Length of value
|
2021-04-30 14:21:21 +02:00
|
|
|
|
{
|
|
|
|
|
_pdfio_value_t temp; // New value
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Range check input...
|
|
|
|
|
if (!dict || !key || !value || !valuelen)
|
|
|
|
|
return (false);
|
|
|
|
|
|
|
|
|
|
// Set the key/value pair...
|
|
|
|
|
temp.type = PDFIO_VALTYPE_BINARY;
|
|
|
|
|
temp.value.binary.datalen = valuelen;
|
|
|
|
|
|
|
|
|
|
if ((temp.value.binary.data = (unsigned char *)malloc(valuelen)) == NULL)
|
|
|
|
|
return (false);
|
|
|
|
|
|
|
|
|
|
memcpy(temp.value.binary.data, value, valuelen);
|
|
|
|
|
|
2021-05-01 13:36:19 +02:00
|
|
|
|
if (!_pdfioDictSetValue(dict, key, &temp))
|
|
|
|
|
{
|
|
|
|
|
free(temp.value.binary.data);
|
|
|
|
|
return (false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (true);
|
2021-04-30 14:21:21 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictSetBoolean()' - Set a key boolean in a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
bool // O - `true` on success, `false` on failure
|
|
|
|
|
pdfioDictSetBoolean(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
|
|
|
|
bool value) // I - Value
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t temp; // New value
|
|
|
|
|
|
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
// Range check input...
|
|
|
|
|
if (!dict || !key)
|
|
|
|
|
return (false);
|
|
|
|
|
|
|
|
|
|
// Set the key/value pair...
|
2021-04-26 02:12:52 +02:00
|
|
|
|
temp.type = PDFIO_VALTYPE_BOOLEAN;
|
|
|
|
|
temp.value.boolean = value;
|
|
|
|
|
|
|
|
|
|
return (_pdfioDictSetValue(dict, key, &temp));
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-07-08 04:06:25 +02:00
|
|
|
|
//
|
|
|
|
|
// 'pdfioDictSetDate()' - Set a date value in a dictionary.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
bool // O - `true` on success, `false` on failure
|
|
|
|
|
pdfioDictSetDate(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
|
|
|
|
time_t value) // I - Value
|
|
|
|
|
{
|
|
|
|
|
_pdfio_value_t temp; // New value
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Range check input...
|
|
|
|
|
if (!dict || !key)
|
|
|
|
|
return (false);
|
|
|
|
|
|
|
|
|
|
// Set the key/value pair...
|
|
|
|
|
temp.type = PDFIO_VALTYPE_DATE;
|
|
|
|
|
temp.value.date = value;
|
|
|
|
|
|
|
|
|
|
return (_pdfioDictSetValue(dict, key, &temp));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictSetDict()' - Set a key dictionary in a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
bool // O - `true` on success, `false` on failure
|
|
|
|
|
pdfioDictSetDict(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
|
|
|
|
pdfio_dict_t *value) // I - Value
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t temp; // New value
|
|
|
|
|
|
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
// Range check input...
|
|
|
|
|
if (!dict || !key || !value)
|
|
|
|
|
return (false);
|
|
|
|
|
|
|
|
|
|
// Set the key/value pair...
|
2021-04-26 02:12:52 +02:00
|
|
|
|
temp.type = PDFIO_VALTYPE_DICT;
|
|
|
|
|
temp.value.dict = value;
|
|
|
|
|
|
|
|
|
|
return (_pdfioDictSetValue(dict, key, &temp));
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictSetName()' - Set a key name in a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
bool // O - `true` on success, `false` on failure
|
|
|
|
|
pdfioDictSetName(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
|
|
|
|
const char *value) // I - Value
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t temp; // New value
|
|
|
|
|
|
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
// Range check input...
|
|
|
|
|
if (!dict || !key || !value)
|
|
|
|
|
return (false);
|
|
|
|
|
|
|
|
|
|
// Set the key/value pair...
|
2021-04-26 02:12:52 +02:00
|
|
|
|
temp.type = PDFIO_VALTYPE_NAME;
|
|
|
|
|
temp.value.name = value;
|
|
|
|
|
|
|
|
|
|
return (_pdfioDictSetValue(dict, key, &temp));
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictSetNull()' - Set a key null in a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
bool // O - `true` on success, `false` on failure
|
|
|
|
|
pdfioDictSetNull(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key) // I - Key
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t temp; // New value
|
|
|
|
|
|
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
// Range check input...
|
|
|
|
|
if (!dict || !key)
|
|
|
|
|
return (false);
|
|
|
|
|
|
|
|
|
|
// Set the key/value pair...
|
2021-04-26 02:12:52 +02:00
|
|
|
|
temp.type = PDFIO_VALTYPE_NULL;
|
|
|
|
|
|
|
|
|
|
return (_pdfioDictSetValue(dict, key, &temp));
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictSetNumber()' - Set a key number in a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
bool // O - `true` on success, `false` on failure
|
|
|
|
|
pdfioDictSetNumber(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
2022-07-06 14:47:52 +02:00
|
|
|
|
double value) // I - Value
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t temp; // New value
|
|
|
|
|
|
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
// Range check input...
|
|
|
|
|
if (!dict || !key)
|
|
|
|
|
return (false);
|
|
|
|
|
|
|
|
|
|
// Set the key/value pair...
|
2021-04-26 02:12:52 +02:00
|
|
|
|
temp.type = PDFIO_VALTYPE_NUMBER;
|
|
|
|
|
temp.value.number = value;
|
|
|
|
|
|
|
|
|
|
return (_pdfioDictSetValue(dict, key, &temp));
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-06-07 14:34:30 +02:00
|
|
|
|
// 'pdfioDictSetObj()' - Set a key indirect object reference in a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
bool // O - `true` on success, `false` on failure
|
2021-06-07 14:34:30 +02:00
|
|
|
|
pdfioDictSetObj(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
|
|
|
|
pdfio_obj_t *value) // I - Value
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t temp; // New value
|
|
|
|
|
|
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
// Range check input...
|
|
|
|
|
if (!dict || !key || !value)
|
|
|
|
|
return (false);
|
|
|
|
|
|
|
|
|
|
// Set the key/value pair...
|
2021-05-04 16:34:17 +02:00
|
|
|
|
temp.type = PDFIO_VALTYPE_INDIRECT;
|
|
|
|
|
temp.value.indirect.number = value->number;
|
|
|
|
|
temp.value.indirect.generation = value->generation;
|
2021-04-26 02:12:52 +02:00
|
|
|
|
|
|
|
|
|
return (_pdfioDictSetValue(dict, key, &temp));
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictSetRect()' - Set a key rectangle in a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
bool // O - `true` on success, `false` on failure
|
|
|
|
|
pdfioDictSetRect(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
|
|
|
|
pdfio_rect_t *value) // I - Value
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t temp; // New value
|
|
|
|
|
|
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
// Range check input...
|
|
|
|
|
if (!dict || !key || !value)
|
|
|
|
|
return (false);
|
|
|
|
|
|
|
|
|
|
// Set the key/value pair...
|
2021-04-26 02:12:52 +02:00
|
|
|
|
temp.type = PDFIO_VALTYPE_ARRAY;
|
|
|
|
|
temp.value.array = pdfioArrayCreate(dict->pdf);
|
|
|
|
|
|
|
|
|
|
pdfioArrayAppendNumber(temp.value.array, value->x1);
|
|
|
|
|
pdfioArrayAppendNumber(temp.value.array, value->y1);
|
|
|
|
|
pdfioArrayAppendNumber(temp.value.array, value->x2);
|
|
|
|
|
pdfioArrayAppendNumber(temp.value.array, value->y2);
|
|
|
|
|
|
|
|
|
|
return (_pdfioDictSetValue(dict, key, &temp));
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictSetString()' - Set a key literal string in a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
bool // O - `true` on success, `false` on failure
|
|
|
|
|
pdfioDictSetString(pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
|
|
|
|
const char *value)// I - Value
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
_pdfio_value_t temp; // New value
|
|
|
|
|
|
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
// Range check input...
|
|
|
|
|
if (!dict || !key || !value)
|
|
|
|
|
return (false);
|
|
|
|
|
|
|
|
|
|
// Set the key/value pair...
|
2021-04-26 02:12:52 +02:00
|
|
|
|
temp.type = PDFIO_VALTYPE_STRING;
|
|
|
|
|
temp.value.string = value;
|
|
|
|
|
|
|
|
|
|
return (_pdfioDictSetValue(dict, key, &temp));
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'pdfioDictSetStringf()' - Set a key formatted string in a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
bool // O - `true` on success, `false` on failure
|
|
|
|
|
pdfioDictSetStringf(
|
|
|
|
|
pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
|
|
|
|
const char *format, // I - `printf`-style format string
|
|
|
|
|
...) // I - Additional arguments as needed
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
char buffer[8192]; // String buffer
|
|
|
|
|
va_list ap; // Argument list
|
|
|
|
|
|
|
|
|
|
|
2021-04-30 14:21:21 +02:00
|
|
|
|
// Range check input...
|
|
|
|
|
if (!dict || !key || !format)
|
|
|
|
|
return (false);
|
|
|
|
|
|
|
|
|
|
// Set the key/value pair...
|
2021-04-26 02:12:52 +02:00
|
|
|
|
va_start(ap, format);
|
|
|
|
|
vsnprintf(buffer, sizeof(buffer), format, ap);
|
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
|
|
return (pdfioDictSetString(dict, key, buffer));
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// '_pdfioDictSetValue()' - Set a key value in a dictionary.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
bool // O - `true` on success, `false` on failure
|
|
|
|
|
_pdfioDictSetValue(
|
|
|
|
|
pdfio_dict_t *dict, // I - Dictionary
|
|
|
|
|
const char *key, // I - Key
|
|
|
|
|
_pdfio_value_t *value) // I - Value
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-05-01 13:36:19 +02:00
|
|
|
|
_pdfio_pair_t *pair; // Current pair
|
2021-04-26 02:12:52 +02:00
|
|
|
|
|
|
|
|
|
|
2021-05-05 03:31:58 +02:00
|
|
|
|
PDFIO_DEBUG("_pdfioDictSetValue(dict=%p, key=\"%s\", value=%p)\n", dict, key, (void *)value);
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// See if the key is already set...
|
|
|
|
|
if (dict->num_pairs > 0)
|
|
|
|
|
{
|
2021-05-01 13:36:19 +02:00
|
|
|
|
_pdfio_pair_t pkey; // Search key
|
|
|
|
|
|
|
|
|
|
pkey.key = key;
|
2021-04-26 02:12:52 +02:00
|
|
|
|
|
2021-05-01 13:36:19 +02:00
|
|
|
|
if ((pair = (_pdfio_pair_t *)bsearch(&pkey, dict->pairs, dict->num_pairs, sizeof(_pdfio_pair_t), (int (*)(const void *, const void *))compare_pairs)) != NULL)
|
2021-04-26 02:12:52 +02:00
|
|
|
|
{
|
|
|
|
|
// Yes, replace the value...
|
2021-05-05 19:51:42 +02:00
|
|
|
|
PDFIO_DEBUG("_pdfioDictSetValue: Replacing existing value.\n");
|
2021-10-31 13:30:08 +01:00
|
|
|
|
if (pair->value.type == PDFIO_VALTYPE_BINARY)
|
|
|
|
|
free(pair->value.value.binary.data);
|
2021-04-26 02:12:52 +02:00
|
|
|
|
pair->value = *value;
|
|
|
|
|
return (true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Nope, add a pair...
|
|
|
|
|
if (dict->num_pairs >= dict->alloc_pairs)
|
|
|
|
|
{
|
|
|
|
|
// Expand the dictionary...
|
2021-05-05 19:51:42 +02:00
|
|
|
|
_pdfio_pair_t *temp = (_pdfio_pair_t *)realloc(dict->pairs, (dict->alloc_pairs + 8) * sizeof(_pdfio_pair_t));
|
2021-04-26 02:12:52 +02:00
|
|
|
|
|
|
|
|
|
if (!temp)
|
2021-05-05 19:51:42 +02:00
|
|
|
|
{
|
|
|
|
|
PDFIO_DEBUG("_pdfioDictSetValue: Out of memory.\n");
|
2021-04-26 02:12:52 +02:00
|
|
|
|
return (false);
|
2021-05-05 19:51:42 +02:00
|
|
|
|
}
|
2021-04-26 02:12:52 +02:00
|
|
|
|
|
|
|
|
|
dict->pairs = temp;
|
2021-05-05 19:51:42 +02:00
|
|
|
|
dict->alloc_pairs += 8;
|
2021-04-26 02:12:52 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pair = dict->pairs + dict->num_pairs;
|
|
|
|
|
dict->num_pairs ++;
|
|
|
|
|
|
|
|
|
|
pair->key = key;
|
|
|
|
|
pair->value = *value;
|
|
|
|
|
|
|
|
|
|
// Re-sort the dictionary and return...
|
2021-05-05 19:51:42 +02:00
|
|
|
|
if (dict->num_pairs > 1 && compare_pairs(pair - 1, pair) > 0)
|
2021-04-26 02:12:52 +02:00
|
|
|
|
qsort(dict->pairs, dict->num_pairs, sizeof(_pdfio_pair_t), (int (*)(const void *, const void *))compare_pairs);
|
|
|
|
|
|
2021-05-05 03:31:58 +02:00
|
|
|
|
#ifdef DEBUG
|
2021-05-10 23:37:57 +02:00
|
|
|
|
PDFIO_DEBUG("_pdfioDictSetValue(%p): %lu pairs\n", (void *)dict, (unsigned long)dict->num_pairs);
|
2023-02-04 02:39:04 +01:00
|
|
|
|
// PDFIO_DEBUG("_pdfioDictSetValue(%p): ", (void *)dict);
|
|
|
|
|
// PDFIO_DEBUG_DICT(dict);
|
|
|
|
|
// PDFIO_DEBUG("\n");
|
2021-05-05 03:31:58 +02:00
|
|
|
|
#endif // DEBUG
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
return (true);
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-28 03:22:34 +02:00
|
|
|
|
//
|
|
|
|
|
// '_pdfioDictWrite()' - Write a dictionary to a PDF file.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
bool // O - `true` on success, `false` on failure
|
|
|
|
|
_pdfioDictWrite(pdfio_dict_t *dict, // I - Dictionary
|
2021-10-24 00:08:16 +02:00
|
|
|
|
pdfio_obj_t *obj, // I - Object, if any
|
2021-04-28 03:22:34 +02:00
|
|
|
|
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);
|
|
|
|
|
|
2021-05-30 03:16:21 +02:00
|
|
|
|
if (length && !strcmp(pair->key, "Length") && pair->value.type == PDFIO_VALTYPE_NUMBER && pair->value.value.number <= 0.0)
|
2021-04-28 03:22:34 +02:00
|
|
|
|
{
|
|
|
|
|
// Writing an object dictionary with an undefined length
|
2021-05-28 16:41:21 +02:00
|
|
|
|
*length = _pdfioFileTell(pdf) + 1;
|
2021-05-05 19:51:42 +02:00
|
|
|
|
if (!_pdfioFilePuts(pdf, " 9999999999"))
|
2021-04-28 03:22:34 +02:00
|
|
|
|
return (false);
|
|
|
|
|
}
|
2021-10-24 00:08:16 +02:00
|
|
|
|
else if (!_pdfioValueWrite(pdf, obj, &pair->value, NULL))
|
2021-04-28 03:22:34 +02:00
|
|
|
|
return (false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Close it up...
|
|
|
|
|
return (_pdfioFilePuts(pdf, ">>"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
2021-04-26 02:12:52 +02:00
|
|
|
|
// 'compare_pairs()' - Compare the keys for two pairs.
|
2021-04-17 02:41:46 +02:00
|
|
|
|
//
|
|
|
|
|
|
2021-04-26 02:12:52 +02:00
|
|
|
|
static int // O - Result of comparison
|
|
|
|
|
compare_pairs(_pdfio_pair_t *a, // I - First pair
|
|
|
|
|
_pdfio_pair_t *b) // I - Second pair
|
2021-04-17 02:41:46 +02:00
|
|
|
|
{
|
2021-04-26 02:12:52 +02:00
|
|
|
|
return (strcmp(a->key, b->key));
|
2021-04-17 02:41:46 +02:00
|
|
|
|
}
|