Add pdfioFileAddOutputIntent API (Issue #104)

This commit is contained in:
Michael R Sweet 2025-04-13 14:16:53 -04:00
parent acd68df592
commit ec64af8b20
No known key found for this signature in database
GPG Key ID: BE67C75EC81F3244
4 changed files with 106 additions and 2 deletions

View File

@ -9,10 +9,12 @@ v1.6.0 - YYYY-MM-DD
(Issue #104)
- Added CMYK JPEG support with embedded ICC profiles or using the CGATS001
profile (Issue #104)
- Now add default grayscale, RGB, and CMYK profile resources to pages as needed
(Issue #104)
- Added `pdfioFileAddOutputIntent` function to adding output intent information
to a PDF file (Issue #104)
- Added `pdfioFileCreateFontObjFromData` function for embedding fonts in
memory (Issue #120)
- Now add default grayscale, RGB, and CMYK profile resources to pages as needed
(Issue #104)
v1.5.3 - YYYY-MM-DD

View File

@ -1489,6 +1489,103 @@ pdfioContentTextShowJustified(
}
//
// 'pdfioFileAddOutputIntent()' - Add an OutputIntent to a file.
//
// This function adds an OutputIntent dictionary to the PDF file catalog.
// The "subtype" argument specifies the intent subtype and is typically
// "GTS_PDFX" for PDF/X, "GTS_PDFA1" for PDF/A, or "ISO_PDFE1" for PDF/E.
// Passing `NULL` defaults the subtype to "GTS_PDFA1".
//
// The "condition" argument specifies a short name for the output intent, while
// the "info" argument specifies a longer description for the output intent.
// Both can be `NULL` to omit this information.
//
// The "cond_id" argument specifies a unique identifier such as a registration
// ("CGATS001") or color space name ("sRGB"). The "reg_name" argument provides
// a URL for the identifier.
//
// The "profile" argument specifies an ICC profile object for the output
// condition. If `NULL`, the PDF consumer will attempt to look up the correct
// profile using the "cond_id" value.
//
// @since PDFio 1.6@
//
void
pdfioFileAddOutputIntent(
pdfio_file_t *pdf, // I - PDF file
const char *subtype, // I - Intent subtype (standard)
const char *condition, // I - Condition name or `NULL` for none
const char *cond_id, // I - Identifier such as registration name or `NULL` for none
const char *reg_name, // I - Registry URL or `NULL` for none
const char *info, // I - Description or `NULL` for none
pdfio_obj_t *profile) // I - ICC profile object or `NULL` for none
{
pdfio_array_t *output_intents; // OutputIntents array in catalog
pdfio_dict_t *intent; // Current output intent
// Range check input...
if (!pdf)
return;
if (!subtype)
{
_pdfioFileError(pdf, "Output intent subtype cannot be NULL.");
return;
}
// Get the OutputIntents array...
if ((output_intents = pdfioDictGetArray(pdfioObjGetDict(pdf->info_obj), "OutputIntents")) != NULL)
{
// See if we already have an intent for the given subtype...
size_t i, // Looping var
count; // Number of output intents
for (i = 0, count = pdfioArrayGetSize(output_intents); i < count; i ++)
{
if ((intent = pdfioArrayGetDict(output_intents, i)) != NULL)
{
const char *csubtype = pdfioDictGetName(intent, "S");
// Current subtype
if (csubtype && !strcmp(csubtype, subtype))
return;
}
}
}
else
{
// Create the OutputIntents array...
if ((output_intents = pdfioArrayCreate(pdf)) == NULL)
return;
pdfioDictSetArray(pdfioObjGetDict(pdf->info_obj), "OutputIntents", output_intents);
}
// Create an intent dictionary...
if ((intent = pdfioDictCreate(pdf)) == NULL)
return;
pdfioDictSetName(intent, "Type", "OutputIntent");
pdfioDictSetName(intent, "S", pdfioStringCreate(pdf, subtype));
if (condition)
pdfioDictSetString(intent, "OutputCondition", pdfioStringCreate(pdf, condition));
if (cond_id)
pdfioDictSetString(intent, "OutputConditionIdentifier", pdfioStringCreate(pdf, cond_id));
if (reg_name)
pdfioDictSetString(intent, "RegistryName", pdfioStringCreate(pdf, reg_name));
if (info)
pdfioDictSetString(intent, "Info", pdfioStringCreate(pdf, info));
if (profile)
pdfioDictSetObj(intent, "DestOutputProfile", profile);
// Add the dictionary to the output intents...
pdfioArrayAppendDict(output_intents, intent);
}
//
// 'pdfioFileCreateBaseFontObj()' - Create one of the base 14 PDF fonts.
//

View File

@ -128,6 +128,7 @@ extern bool pdfioContentTextShowf(pdfio_stream_t *st, bool unicode, const char
extern bool pdfioContentTextShowJustified(pdfio_stream_t *st, bool unicode, size_t num_fragments, const double *offsets, const char * const *fragments) _PDFIO_PUBLIC;
// Resource helpers...
extern void pdfioFileAddOutputIntent(pdfio_file_t *pdf, const char *subtype, const char *condition, const char *cond_id, const char *reg_name, const char *info, pdfio_obj_t *profile) _PDFIO_PUBLIC;
extern pdfio_obj_t *pdfioFileCreateFontObjFromBase(pdfio_file_t *pdf, const char *name) _PDFIO_PUBLIC;
extern pdfio_obj_t *pdfioFileCreateFontObjFromData(pdfio_file_t *pdf, const void *data, size_t datasize, bool unicode) _PDFIO_PUBLIC;
extern pdfio_obj_t *pdfioFileCreateFontObjFromFile(pdfio_file_t *pdf, const char *filename, bool unicode) _PDFIO_PUBLIC;

View File

@ -124,6 +124,10 @@ pdfioFileClose(pdfio_file_t *pdf) // I - PDF file
{
ret = false;
// Add default OutputIntent for PDF/A CMYK printing...
pdfioFileAddOutputIntent(pdf, /*subtype*/"GTS_PDFA1", /*condition*/"CMYK", /*cond_id*/"CGATS001", /*reg_name*/NULL, /*info*/"CMYK Printing", /*profile*/pdf->cgats001_obj);
// Close and write out the last bits...
if (pdfioObjClose(pdf->info_obj) && write_pages(pdf) && pdfioObjClose(pdf->root_obj) && write_trailer(pdf))
ret = _pdfioFileFlush(pdf);
}