Creating an ICC Profile
The following steps create a new ICC profile and then add three tags to it. The first tag will be created from scratch. The second tag will be taken from an existing ICC profile and then added to the new ICC profile after modifying it. The final tag will be taken from another ICC profile and added to the new ICC profile without modification.
1. |
Define the following variables: |
ICCPROFILEEXT oldIccProfile, newIccProfile;
SYSTEMTIME sysTime;
ICCTAG_DATE_TIME_TYPE iccDateTimeTagType;
ICCTAG_XYZ_TYPE iccXyzTagType;
ICCTAG_SIGNATURE_TYPE iccSignatureTagType;
2. |
Initialize both the new ICC profile to be created (newIccProfile), and the already existing one (oldIccProfile): |
L_InitICCProfile(&oldIccProfile, sizeof(ICCPROFILEEXT));
L_InitICCProfile(&newIccProfile, sizeof(ICCPROFILEEXT));
3. |
Fill the oldIccProfile structure as an existing ICC profile from a specific file: |
L_FillICCProfileFromICCFile(TEXT("d:\\ICCv42.icc"), &oldIccProfile);
4. |
Initialize the header of the new ICC Profile: |
L_InitICCHeader(&newIccProfile);
5. |
Copy the header of the existing ICC profile as it is in the header of the new ICC profile: |
L_SetICCCMMType(&newIccProfile, oldIccProfile.pIccHeader->nCmmID);
newIccProfile.pIccHeader->uVersion = oldIccProfile.pIccHeader->uVersion;
L_SetICCDeviceClass(&newIccProfile, oldIccProfile.pIccHeader->uDeviceClass);
L_SetICCColorSpace(&newIccProfile, oldIccProfile.pIccHeader->uColorSpace);
L_SetICCConnectionSpace(&newIccProfile, oldIccProfile.pIccHeader->uPCS);
L_SetICCDateTime(&newIccProfile, &oldIccProfile.pIccHeader->DateTime);
L_SetICCPrimaryPlatform(&newIccProfile, oldIccProfile.pIccHeader->uPlatform);
L_SetICCFlags(&newIccProfile, oldIccProfile.pIccHeader->uFlags);
L_SetICCDevManufacturer(&newIccProfile,
oldIccProfile.pIccHeader->nManufacturer);
L_SetICCDevModel(&newIccProfile, oldIccProfile.pIccHeader->uModel);
L_SetICCDeviceAttributes(&newIccProfile,
oldIccProfile.pIccHeader->uAttributes);
L_SetICCRenderingIntent(&newIccProfile,
oldIccProfile.pIccHeader->uRenderingIntent);
L_SetICCCreator(&newIccProfile, oldIccProfile.pIccHeader->nCreator);
6. |
Create tag #1 and call it calibrationDateTimeTag, fill it with the current system time, then insert it into the new ICC profile: |
memset(&iccDateTimeTagType, 0, sizeof(ICCTAG_DATE_TIME_TYPE));
GetSystemTime(&sysTime);
iccDateTimeTagType.DateTime.uYear = sysTime.wYear;
iccDateTimeTagType.DateTime.uMonth = sysTime.wMonth;
iccDateTimeTagType.DateTime.uDay = sysTime.wDay;
iccDateTimeTagType.DateTime.uHours = sysTime.wHour;
iccDateTimeTagType.DateTime.uMinutes = sysTime.wMinute;
iccDateTimeTagType.DateTime.uSeconds = sysTime.wSecond;
L_SetICCTagData(&newIccProfile, (L_UCHAR*) &iccDateTimeTagType, CalibrationDateTimeTag, DateTimeTypeSig);
7. |
Tag #2 is called the mediaWhitePointTag. It is obtained from the existing ICC Profile. Instead of the existing profile's values, random values will be generated and these will be inserted into the new ICC profile: |
// get mediaWhitePointTag tag from the excising ICC profile
L_GetICCTagData(&oldIccProfile, (L_UCHAR*) &iccXyzTagType,
MediaWhitePointTag);
// change it's values
iccXyzTagType.pXYZNumData[0].nX = L_DoubleTo2bFixed2bNumber(0.123);
iccXyzTagType.pXYZNumData[0].nY = L_DoubleTo2bFixed2bNumber(0.456);
iccXyzTagType.pXYZNumData[0].nZ = L_DoubleTo2bFixed2bNumber(0.789);
// insert it in the new ICC profile
L_SetICCTagData(&newIccProfile, (L_UCHAR*) &iccXyzTagType,
MediaWhitePointTag, XYZTypeSig);
8. |
Tag #3 is called the technologyTag. It is obtained from the existing ICC Profile. This tag will be inserted it into the new ICC profile without modifying its values. |
// get the technologyTag
L_GetICCTagData(&oldIccProfile, (L_UCHAR*) &iccSignatureTagType, TechnologyTag);
// insert it in the new ICC profile
L_SetICCTagData(&newIccProfile, (L_UCHAR*) &iccSignatureTagType, TechnologyTag, SignatureTypeSig);
9. |
Generate the Profile ID. |
// generate the profile ID
L_SetICCProfileId(&newIccProfile);
10. |
Generate the pData pointer of the new ICC profile and create the new ICC profile: |
// Generate the pData Pointer
L_GenerateICCPointer(&newIccProfile);
// Create the ICC file
L_GenerateICCFile(&newIccProfile, TEXT("d:\\NewICCv42.icc"));
11. |
Finally, free the handles of the existing and newly created ICC profiles: |
L_FreeICCProfile(&oldIccProfile);
L_FreeICCProfile(&newIccProfile);