无效的ICC配置文件使用WIC

我一直在努力弄清楚microsoft WIC / WCS库在这里所做的事情,并且希望精通Windows颜色管理的任何人都可以提供帮助。该API的文档非常糟糕。

我正在使用OpenColourProfile阅读带有嵌入式ICC配置文件的JPEG,但是Windows对于某些图像似乎无法正确解析嵌入式ICC信息。对于其他人来说,也可以。但是,即使它无法使用Windows API解析标头信息,我也能够正确显示所有图像,但这只是对嵌入式ICC配置文件标头信息的解析是错误的。


不起作用

使用exif_t​​ool工具显示无法通过我的代码运行的图像的ICC配置文件标题信息,exif_t​​ool会正确返回:

Profile CMM Type                : Adobe Systems Inc.
Profile Version                 : 2.1.0
Profile Class                   : Display Device Profile
Color Space Data                : RGB
Profile Connection Space        : XYZ
Profile Date Time               : 2000:08:11 19:51:59
Profile File Signature          : acsp
Primary Platform                : Apple Computer Inc.
CMM flags                       : Not Embedded,Independent
Device Manufacturer             : none
Device Model                    :
Device Attributes               : Reflective,Glossy,Positive,Color
Rendering Intent                : Perceptual
Connection Space Illuminant     : 0.9642 1 0.82491
Profile Creator                 : Adobe Systems Inc.
Profile ID                      : 0
Profile Copyright               : Copyright 2000 Adobe Systems Incorporated
Profile Description             : Adobe RGB (1998)
Media White Point               : 0.95045 1 1.08905
Media Black Point               : 0 0 0
Red Tone Reproduction Curve     : (Binary data 14 bytes,use -b option to extract)
Green Tone Reproduction Curve   : (Binary data 14 bytes,use -b option to extract)
Blue Tone Reproduction Curve    : (Binary data 14 bytes,use -b option to extract)
Red Matrix Column               : 0.60974 0.31111 0.01947
Green Matrix Column             : 0.20528 0.62567 0.06087
Blue Matrix Column              : 0.14919 0.06322 0.74457

在我的代码中读取ICC配置文件标头后,Windows将CMM类型返回为0000(未定义)(请参见下文)。同样,版本标记的解析地址是v2.0(0x02000000),而不是上面的exif_t​​ool输出中所示的v2.1。

无效的ICC配置文件使用WIC

此外,在此之后,一个查询(在我的代码中)返回ICC标签0x64657363(ProfileDescription)返回“ opRGB”而不是“ Adob​​e RGB(1998)”。

就此图像的EXIF数据而言,颜色空间被定义为“未校准”,并且指定了“互操作性索引”,其值为“ R03”,据我理解,该互操作性索引应解释为Adobe RGB。

工作


使用另一个带有嵌入式Adobe RGB(1998)配置文件的JPG,我通过exif_t​​ool运行了它,并显示:

Profile CMM Type                : Adobe Systems Inc.
Profile Version                 : 2.1.0
Profile Class                   : Display Device Profile
Color Space Data                : RGB
Profile Connection Space        : XYZ
Profile Date Time               : 1999:06:03 00:00:00
Profile File Signature          : acsp
Primary Platform                : microsoft Corporation
CMM flags                       : Not Embedded,Color
Rendering Intent                : Media-Relative Colorimetric
Connection Space Illuminant     : 0.9642 1 0.82491
Profile Creator                 : Adobe Systems Inc.
Profile ID                      : 0
Profile Copyright               : Copyright (c) 1999 Adobe Systems Incorporated. All     Rights Reserved.
Profile Description             : Adobe RGB (1998)
Media White Point               : 0.95045 1 1.08905
Media Black Point               : 0 0 0
Red Tone Reproduction Curve     : (Binary data 14 bytes,use -b option to extract)
Red Matrix Column               : 0.60974 0.31111 0.01947
Green Matrix Column             : 0.20528 0.62567 0.06087
Blue Matrix Column              : 0.14919 0.06322 0.74457

使用OpenColourProfile时,我的代码(使用Windows API)正确解析了标头信息:

无效的ICC配置文件使用WIC

在此之后,一个查询(在我的代码中)正确返回ICC标签0x64657363(ProfileDescription),将返回“ Adob​​e RGB(1998)”。

根据该图像的EXIF数据,颜色空间被定义为“未校准”,并且未指定“互操作性指数”。

代码


    /* COLOUR PROFILE MANAGEMENT */
    IWICColorContext* pContextsrc = NULL;
    IWICColorContext* pContextDst = NULL;

    hr = factory->CreateColorContext(&pContextsrc);
    if (!SUCCEEDED(hr))
        return nullptr;

    UINT numColourContexts = 0;
    hr = wic->mFrame->getcolorContexts(1,&pContextsrc,&numColourContexts);

    if (numColourContexts > 0)
    {
        hr = factory->CreateColorContext(&pContextDst);
        if (!SUCCEEDED(hr))
            return nullptr;

        WCHAR destColourContextFilename[_MAX_PATH + 1];
        DWORD destColourContextFilenameSize = sizeof(destColourContextFilename);

        if (getcolorDirectory(NULL,destColourContextFilename,&destColourContextFilenameSize))
        {
            hr = StringCchCatW(destColourContextFilename,sizeof(destColourContextFilename) / sizeof(destColourContextFilename[0]),L"\\sRGB Color Space Profile.icm");
        }
        else
        {
            hr = E_UNEXPECTED;
        }

        if (SUCCEEDED(hr))
        {
            hr = pContextDst->InitializeFromFilename(destColourContextFilename);
        }


        if (SUCCEEDED(hr))
        {
            hr = factory->CreateColorTransformer(&wic->pColorTransform);
        }

        if (SUCCEEDED(hr))
        {
            hr = wic->pColorTransform->Initialize(wic->mFrame.get(),pContextsrc,pContextDst,wic->mPixelFormat);

            if (!SUCCEEDED(hr))
            {
                return nullptr;
            }
        }

            //  WICColorContextUninitialized = 0,//  WICColorContextProfile = 0x1,//  WICColorContextExifColorSpace = 0x2
            WICColorContextType type;
            pContextsrc->GetType(&type);

            if (type == WICColorContextType::WICColorContextProfile)
            {
                UINT cbProfile = 0;
                hr = pContextsrc->GetProfileBytes(0,NULL,&cbProfile);

                if (!SUCCEEDED(hr))
                    return nullptr;

                VOID* pvProfile = NULL;

                if (SUCCEEDED(hr))
                {
                    // allocate the block
                    pvProfile = HeapAlloc(
                        GetProcessHeap(),HEAP_ZERO_MEMORY,cbProfile);

                    hr = pvProfile ? S_OK : E_FAIL;
                }

                UINT cbSize = 0;
                if (SUCCEEDED(hr))
                {
                    // copy the profile into the block
                    hr = pContextsrc->GetProfileBytes(cbProfile,(BYTE*)pvProfile,&cbSize);
                }

                // ***Open the memory block as a HPROFILE***
                HPROFILE hProfile = NULL;

                // fill out a PROFILE structure
                PROFILE prof =
                {
                      PROFILE_MEMBUFFER,pvProfile,cbProfile
                };

                // create the HPROFILE
                if (SUCCEEDED(hr))
                {
                    /*hProfile = WcsOpenColorProfile(
                        &prof,PROFILE_READ,FILE_SHARE_READ,OPEN_EXISTING,0);*/

                    hProfile = OpenColorProfile(
                            &prof,OPEN_EXISTING);


                    hr = hProfile ? S_OK : E_FAIL;
                    HeapFree(GetProcessHeap(),pvProfile);
                }

                PROFILEHEADER ph;
                getcolorProfileHeader(hProfile,&ph);


                DWORD size = 100;
                CHAR description[100];
                for (int i = 0; i < 100; i++)
                {
                    description[i] = '\0';
                }
                BOOL b;
                BOOL s = getcolorProfileElement(hProfile,0x64657363,12,&size,&description,&b);
                string profileDescription = std::string(description);

变量ph代表上面的蓝色图像屏幕截图,profileDescription代表ICC配置文件描述(仅对一个图像有效,而对另一幅图像无效)


ICC标头之间的差异

我已经总结了exif_t​​ool报告的ICC标头信息中的差异,这导致Windows API无法正确解析嵌入的ICC标头信息:

工作

Profile Date Time               : 2000:08:11 19:51:59
Primary Platform                : Apple Computer Inc.
Rendering Intent                : Perceptual
Profile Copyright               : Copyright 2000 Adobe Systems Incorporated

不起作用

Profile Date Time               : 1999:06:03 00:00:00
Primary Platform                : microsoft Corporation
Rendering Intent                : Media-Relative Colorimetric
Profile Copyright               : Copyright (c) 1999 Adobe Systems Incorporated. All Rights Reserved.

其他图像编辑软件将两个图像正确报告为“ Adob​​e RGB(1998)”

当嵌入式ICC信息以microsoft平台为目标时,似乎Windows API不喜欢它(?)

可能是由于缺少“互操作性索引”(对于无效的映像指定为“ R03”,对于有效的映像指定为“ R03”),但是如果是这种情况,这似乎是Windows中的错误(?)

也许“ Adob​​e RGB”和“ Adob​​e RGB(1998)”是两个不同的配置文件,而所有其他将它们都报告为“ Adob​​e RGB(1998)”的软件根本无法区分它们吗? / p>

我的头很痛……有人知道这是怎么回事吗?

欢呼

编辑:

工作图像(使用Windows API读取时,配置文件说明= Adob​​e RGB(1998)):

无效的ICC配置文件使用WIC

不起作用(使用Windows API读取时,配置文件说明= opRGB):

无效的ICC配置文件使用WIC

nabela123 回答:无效的ICC配置文件使用WIC

Maybe Rendering Intent:感知意味着在 CMM 中不需要。另一方面,相对于介质的色度...

此外,opRGB 与 Adob​​e RGB 1998 相同(在原色和传递函数方面)。参见 IEC 61966-2-5-2007。我有标准,矩阵到XYZ也是一样的。即使是黑色 XYZ 也是一样。甚至“归一化绝对 XYZ 三色值进行编码”也是一样的,并说“XYZ 三色值 0,000 0,000 0 应该对应于观众 观察到的参考显示黑点”和“归一化 XYZ 三色值 0,9505, 1,0000,1,0891 应该对应于参考显示亮度级别和白点”,就像在ICC配置文件中一样。

本文链接:https://www.f2er.com/3129894.html

大家都在问