The ICC Profile format is defined by the International Color Consortium (ICC). For background on the origination and purpose of this format, refer to https://www.color.org/index.xalter.
Creating an ICC Profile
To determine whether an image file has an ICC Profile embedded in it, call the L_HasICCProfile function. To determine whether the color conversion is valid for the conversion process, call the L_ClrIsValid. To set up the conversion parameters, call the L_ClrSetConversionParams function.
To create an ICC profile, start by calling L_InitICCProfile to initialize an ICC profile structure (ICCPROFILEEXT). This must be called before creating a new profile or loading an existing profile. Within the ICCPROFILEEXT structure is an ICCHEADER structure that contains header information for the profile. Once the ICCPROFILEEXT structure has been initialized, the header must be initialized by calling L_InitICCHeader. This sets the members of the ICCHEADER structure to their default values. The following functions can be used to change the ICCHEADER values from default values to custom values:
The ICC Profile can also include tags. Tags can be inserted in an ICC profile, created but not inserted, or deleted. To insert a tag in an ICC profile, do the following:
Define a structure of the same "type" as the tag to be created.
Fill the structure with the required data.
Call the L_SetICCTagData function to insert the tag into the ICC profile.
Tags are of various types. These types have a signature associated with them to identify them. Tags also have signatures associated with them. One or both of these signatures may be used when creating, inserting or deleting tags. To get the signature of a specific tag type, call the L_GetICCTagTypeSig function. For more information on tags, types and signatures, please refer to the documentation available through https://www.color.org/index.xalter.
When working with ICC profiles, it may be necessary to convert values from one form to another. Variables of the type L_IccS15Fixed16Number, or L_IccU16Fixed16Number require data in a 2 bytes fixed, 2 bytes number form. The L_DoubleTo2bFixed2bNumber function converts a double value into a 2 bytes fixed, 2 bytes number form, allowing the user to set these variables. The L_2bFixed2bNumberToDouble function converts a 2 bytes fixed, 2 bytes number value into a double value, allowing the user to get data from these variables.
Similarly, the type L_IccU8Fixed8Number requires data in a 1 byte fixed, 1 byte number form. The L_DoubleToU8Fixed8Number function converts a double value into a 1 byte fixed, 1 byte number form. The L_U8Fixed8NumberToDouble function converts a 1 byte fixed, 1 byte number value into a double value.
The pData pointer of the ICCPROFILEEXT structure points to a block of memory that contains the ICC profile as a whole. This pointer does not generate automatically after each new tag added or deleted. Therefore, to regenerate a pointer to the updated profile, call the L_GenerateICCPointer function. Please note however, that before calling any of the L_GenerateICCFile or L_SaveICCProfile functions, make sure that the uDataSize and pData pointer of the ICCPROFILEEXT has the right data either by loading an ICC profile into them, or by calling the L_GenerateICCPointer to generate them.
The user can export the information of some tags into a buffer of sequential bytes using the following functions:
L_ConvertCurveTypeToBuffer, converts the information of an ICCTAG_CURVE_TYPE structure (CurveType tag) into one buffer of sequential bytes.
L_ConvertCLUTToBuffer, converts the information of an ICC_CLUT8 or ICC_CLUT16 structure (the color of the lookup table data used into LutAToBType and LutBToAType tags) into one buffer of sequential bytes.
L_ConvertParametricCurveTypeToBuffer, converts the information of an ICCTAG_PARAMETRIC_CURVE_TYPE structure (ParametricCurveType tag) into one buffer of sequential bytes. To retrieve the number of parameters of a parametric curve type function, call the L_GetParametricCurveNumberOfParameters function. This number of parameters will be used in calculating the size of the buffer that will be filled by the converted data.
Loading an ICC Profile
ICC profiles can be saved to ICC files or embedded in image files and loaded at a later date. Before loading an existing ICC profile from a saved file, the L_InitICCProfile function must be called to initialize the ICC profile structure.
To load an ICC profile from an image file, call L_LoadICCProfile. This function loads the pData member of the ICCPROFILEEXT structure with a pointer to one block of memory that contains the entire ICC profile. It also loads the uDataSize member with the size of the profile. Once this information has been loaded, call L_FillICCProfileStructure to extract the ICC profile information from the memory block and fill the appropriate members of the ICCPROFILEEXT structure.
A profile structure can also be loaded directly from an ICC profile file, using the L_FillICCProfileFromICCFile function.
Saving an ICC Profile
Freeing an ICC Profile
When an ICC profile structure is no longer needed, free the structure by calling L_FreeICCProfile.