Branching out the XCPD library…

Hi everyone.

I am continuing work on the XCPD project.  At the same time, I will also be deriving a general library to be used outside of the CPD.  Since the XCPD is actually a prototype model for color-managed printing, much of the work done there can be extended – with modifications to the current XCPD code – to other projects (such as Krita).

Naming the new library is a task in it of itself, and I would appreciate some help.  There are a few acronyms that jump to mind, but I am not sure if they are usable:

CMPL (Color-Managed Print Library)

CoMPeX (Color-Managed Printing eXtension)

-Joe

XCPD Manual (Part 3d)

The XCPD Color Management API

Profile Selection Overview (Alternate)

This is a continuation of the profile selection explanation of Part 3c.

In the case where a static PPD file does not have options to read in ICC profile mode selection, the XCPD CM API provides an explicit solution that uses xcpdCM_setProfileFromPPD2(). This function requires an additional xcpdcm_selectormode_t enum parameter, which will have been set each time a user selects an ICC selection option directly from the UI.

Its use is demonstrated by the following extension to the previous code tutorial:

QString iccModeString;
QComboBox iccModeComboBox;

xcpd_cm_t* cm_obj = xcpdCM_initialize();
xcpdcm_selectormode_t mode;

ppd_file_t* ppd = ppdOpenFile("ppdfile.ppd");

// ...
// The following is the ICC profile selection segment
// in the UI.
// ...
iccModeString = iccModeComboBox.currentText();

if(iccModeString == "Auto Set")
  mode = XCPDCM_AUTOSELECT_MODE;
else if (iccModeString == "Application Set")
  mode = XCPDCM_SYSTEMSELECT_MODE;
// In this case, we must explicitly set a profile into XCPDCM.
else if (iccModeString == "Manual") {
  mode = XCPDCM_USERSELECT_MODE; 
  QString userSelection = QFileDialog::getOpenFileName( ... );
  const char* user_profile = userSelection.toLocal8Bit();

  xcpdCM_setProfile(user_profile, cm_obj);  
}
// ...
// The last segment of the code will call a refresh
// of the profile settings based on ICC mode...
// ...
xcpdcm_sstatus_result = xcpdCM_setProfileFromPPD2(cm_obj,
                                                     ppd,                                                                               
                                                    mode);

XCPD Manual (Part 3c)

The XCPD Color Management API

Profile Selection Overview

Note: The following assumes that a “ICC color profile” option is located in the PPD, ensuring that the user-specified ICC selection option is already within the ppd_file_t* object.  An alternative solution for PPDs without this mechanism will be mentioned in Part 3d.

The XCPDCM Selector Module handles the profile selection code via Oyranos, a well-known color management system (CMS).  Its job is to receive configuration data from a PPD file – specifically during the selection of options by the user in the print dialog – and apply the profile-selection workflow as recommended here.  Based on the settings marked in the PPD object, a profile will thus be stored in an xcpd_cm_t* object, which will be available for PDF transport (see Part 3B of this manual for details on the PDF rendering code).

A function named xcpdCM_setProfileFromPPD() is to be called in order to initiate the profile-selection sequence.  A ppd_file_t* object must be marked with the user-selected options prior to sending it into this function, along with an xcpd_cm_t* object.  What is returned is both the xcpd_cm_t* object with an appropriate profile, and a xcpdcm_sstatus_t result enumeration.

Here is a snippet of the code:

xcpd_cm_t* cm_obj = xcpdCM_initialize();
ppd_file_t* ppd = ppdOpenFile("ppdfile.ppd");

//...
// Select dialog options by marking the PPD file object.
// ...

xcpdcm_sstatus_t result = xcpdCM_setProfileFromPPD(cm_obj,
                                                   ppd);
if(result != XCPDCM_SELECTOR_INVALID_PPD ||
   result != XCPDCM_SELECTOR_NOPROFILE)
 puts(xcpdCM_getProfile(cm_obj));

If desired, the xcpdcm_sstatus_t enumeration can be returned in the dialog code to check on the result of the function.  The following are the enumeration values that can be returned:

XCPDCM_SELECTOR_INVALID_PPD
XCPDCM_SELECTOR_USERPROFILE_SET
XCPDCM_SELECTOR_SYSTEMPROFILE_SET
XCPDCM_SELECTOR_AUTOPROFILE_SET
XCPDCM_SELECTOR_CUPSFALLBACK_SET
XCPDCM_SELECTOR_OYDEFAULT_SET
XCPDCM_SELECTOR_NOPROFILE

XCPD Manual (Part 3b)

The XCPD Color Management API

PDF Rendering Overview

The XCPDCM API is able render a spool-ready PDF file by way of a call to the xcpdCM_setSpoolPdf() function.  It is required that the XCPD CM object contain a PDF file set prior to using this (by way of xcpdCM_setPdfFile()).

It’s important to note that the PDF file loaded in the xcpd_cm_t* object will be modified accordingly, so it is necessary to load a copy of the PDF file for rendering purposes.

Internally, the rendering is done by way of the XCPDCM renderer module.  It follows the proposed “pre-flight” workflow of checking for a PDF OutputIntent, tagging the PDF with an ICC Colorspace, and embedding a possible profile set by a user – much of this is invisible to the dialog programmer.

The argument required is the address of a xcpd_cm_t* object, while an optional xcpdcm_rstatus_t enumeration value is returned:

int error = xcpdCM_setPdfFile("myPdf.pdf", cm_obj);

if(!error) {
  xcpdcm_rstatus_t render_status;
  render_status = xcpdCM_setSpoolPdf(cm_obj);
}

The renderer status value will depend on the contents of the PDF file and whether or not the user has chosen a profile in the dialog.  The latter case requires a prior call to xcpdCM_setProfile()  or   xcpdCM_setProfileFromPPD() (which will be outlined in the final part of the API manual).  The enumerations that are returned can include the following:

XCPDCM_PDF_OUTPUTINTENT_EXISTS (PDF already has an OutputIntent.)

XCPDCM_PDF_COLORSPACE_SET (Colorspace has been tagged with an Assumed profile.)

XCPDCM_PDF_NEWPROFILE_EMBEDDED (A user-selected profile has been embedded into the PDF.)

XCPDCM_PDF_INVALID_FILE (The PDF is invalid)

In all but the final case,  a flag will be set in the XCPD CM object to indicate that the spool file is ready.  This can directly be checked by way of the  xcpdCM_isPDFReady() function:

xcpdCM_setSpoolPdf(cm_obj);

if(!xcpdCM_isPDFReady(cm_obj))
 puts("Error: PDF file has not been properly rendered!");

XCPD Manual (Part 3a)

The XCPD Color Management API

(The following is a draft of the API documentation. This is part 1.)

Overview

The XCPD CM API is a small, internal API that will bridge the print dialog and the XCPD Color Management layer.  It was created for hiding the color management details from the dialog code, and freeing the dialog programmer from concerns over the color management process.

While initially coded for the XCPD, the XCPD CM API is itself a prototype for a more ‘generic’ interface that can be used to attach color management to *any* print dialog.

Basic Functions

An XCPD CM object is used to help carry out printer color management throughout the XCPD.  This ‘xcpd_cm_t‘ object will hold and transport the necessary color management data throughout the print workflow.  More specifically, the object should be used during, and in this order, the “profile selection” and “pdf rendering” stages of the workflow.

The XCPD CM object can be initialized by way of the following:

xcpd_cm_t* cm_obj = xcpdCM_initialize();

All functions in the API are prefixed with “xcpdCM_”, followed by the function name (in this case, the function name is ‘initialize‘).

An important use of the XCPD CM object is in keeping track of the PDF and ICC profile files throughout the workflow.  These can explicitly be set in the object using the ‘setProfile‘ and ‘setPdfFile‘ functions:

int error = 0;
error = xcpdCM_setProfile("sRGB.icc", cm_obj);
error = xcpdCM_setPdfFile("myPdf.pdf", cm_obj);

File name strings are passed in the first argument, while the second argument requires passing in an XCPD CM object pointer.  As used here and in many of the XCPD CM API functions, error values are returned with ‘0’ (for a successful operation) or ‘1’ (unsuccessful operation).

Getting the file string values require using the ‘getProfile‘ and ‘getPdfFile‘ functions:

char* profile_string = xcpdCM_getProfile(cm_obj);
char* pdf_string = xcpdCM_getPdfFile(cm_obj);

To close and free memory in an XCPD CM instance, use the ‘close‘ function:

xcpdCM_close( cm_obj );

XCPD Manual (Part 2)

XCPD Color Management Scheme

CM Abstraction Overview

The XCPD Color Management Layer is the intermediate abstraction between the dialog and the internal color management code.  It rests just below the XCPD, keeping the CM code hidden from the dialog programmer.  This layer contains two XCPD CM Modules, one that provides the processing of XCPD’s profile-selection functionality, and the other its PDF rendering capabilities.  The former is handled by the Oyranos APIs and the latter will primarily use Ghostscript.

In order to establish a bridge between the dialog interface and the internal CM code, the XCPD CM Layer contains the XCPD Color Management API, which will provide functions to allow the dialog programmer to send and receive color management information (without ever needing to know how the CM code is implemented internally).

XCPD Color Management Layer

The goal behind the XCPD Color Management Layer is to make color management in the printing dialog simple.  That is, the printer dialog programmer shouldn’t have to know how color management works – only that by following the workflow model, and invoking the appropriate function into the XCPD CM Layer will the dialog programmer know that color management will simply happen.  Strings are attached in the dialog, but the color management “puppeteer” is always invisible.

Outside libraries (Oyranos/Ghostscript) are linked here, although more specifically to the XCPD CM Modules.

XCPD CM Modules

The XCPD CM Layer contains two color management modules, which are considered to be the processing components of the layer:

-The “Profile Selection” module is essentially an extension of the Oyranos API, providing support for XCPD’s profile-selector.  It uses the Oyranos Core to look up, parse, and rank ICC profiles, as well as the Oyranos/CUPS module to obtain printer-related color information from the PPD.

-The “PDF Renderer” module uses the Ghostscript interpreter to handle profiles inside a PDF file.  Its duties include checking for the existence of the OutputIntent in the PDF and tagging a DeviceXXX space with the appropriate ICC profile.

Each module is stored as a separate source file.  The modules are tasked to perform their duties as invoked by the dialog programmer through the XCPD Color Management API.

XCPD Color Management API*

This is the interface that binds both the dialog and the XCPD CM Layer together.  The API’s goal is to not concern the dialog programmer with the details of color management, but rather its workflow as it relates to printing.

Each API function will call an appropriate module from within the CM layer:  A call to, say, “xcpdCM_getCalibratedProfile()” will invoke the Profile Selection module internally and return a profile to the dialog.  Calling a function such as “xcpdCM_checkOutputintent()” will invoke code in the PDF Renderer module and return an int (true or false).

All of the API code is contained in its own source file, and is to be included in the dialog with the statement #include “xcpdcm.h”.

Functions in the XCPD module use the following naming format:

xcpdCM_functionName()

(Where “xcpdCM” is the prefix followed by an underscore, and the name of the function in lower camel case.)

An xcpdCM structure will be used to pass color-related information from the dialog, and passed to the XCPD Color Management Layer through one of the xcpdCM functions. . .

*More details regarding the xcpdCM structure and the entire API will be available in Part 3.  All updates to this draft will be made on the ColourWiki page.