I have been struggling many days with this issue and can't find any explanation!
Background:
I'm creating a color managed photo editing app on Windows with VC9+MFC, and using WCS(Windows Color System) APIs to convert pixels from photo embedded color profile to the monitor's profile.
My monitor has been calibrated with the "Windows Display Calibration", and created a profile named "CalibratedDisplayProfile-x.icc".
Problem:
When I convert pixels from "ProPhoto RGB" to monitor's profile, the color in the dark area shifts, the tint turns green. This doesn't happen in midtone/highlights if the target profile is sRGB. Here're the screen-shots.
Test:
To simplify the problem, I wrote some test codes to translate a single color, but the test result really makes me confused. The source color "c0" is RGB(0,0,65535), but the output color "c1" is RGB(0,0,0)!! And function "CheckColor" fails with error "Invalid Arguments"...
How could this happen? Am I doing something wrong?
You can download the two profiles here: Color Profiles
Thanks very much!
CString strProfilePath = _T("C:\\Windows\\System32\\spool\\drivers\\color\\");
CString strSrcProfile = strProfilePath + _T("ProPhoto.icm");
CString strDstProfile = strProfilePath + _T("CalibratedDisplayProfile-2.icc");
PROFILE pf = {0};
pf.dwType = PROFILE_FILENAME;
pf.pProfileData = (PVOID)strSrcProfile.GetBuffer();
pf.cbDataSize = (strSrcProfile.GetLength() + 1) * sizeof(TCHAR);
HPROFILE hSrcProfile = ::OpenColorProfile( &pf, PROFILE_READ, FILE_SHARE_READ, OPEN_EXISTING );
pf.pProfileData = (PVOID)strDstProfile.GetBuffer();
pf.cbDataSize = (strDstProfile.GetLength() + 1) * sizeof(TCHAR);
HPROFILE hDstProfile = ::OpenColorProfile( &pf, PROFILE_READ, FILE_SHARE_READ, OPEN_EXISTING );
HPROFILE hProfiles[2];
hProfiles[0] = hSrcProfile;
hProfiles[1] = hDstProfile;
DWORD dwIndents[2] = { INTENT_RELATIVE_COLORIMETRIC, INTENT_RELATIVE_COLORIMETRIC };
HTRANSFORM hTransform = ::CreateMultiProfileTransform( hProfiles, 2, dwIndents, 2, BEST_MODE, INDEX_DONT_CARE );
COLOR c0, c1;
c0.rgb.red = 0;
c0.rgb.green = 0;
c0.rgb.blue = 0xffff;
::TranslateColors( hTransform, &c0, 1, COLOR_RGB, &c1, COLOR_RGB );
BYTE btResult = 0;
::CheckColors( hTransform, &c0, 1, COLOR_RGB, &btResult );
::DeleteColorTransform( hTransform );
::CloseColorProfile( hSrcProfile );
::CloseColorProfile( hDstProfile );