Неверный профиль ICC возвращает opRGB из WCS с использованием WIC - PullRequest
1 голос
/ 10 ноября 2019

Я ломал голову, пытаясь понять, что здесь делает библиотека Microsoft WIC / WCS, и был бы признателен за любую помощь любому, кто разбирается в управлении цветом Windows. Документация по этому API ужасна.

Я читаю JPEG со встроенным профилем ICC, используя OpenColourProfile, но Windows, похоже, неправильно анализирует встроенную информацию ICC для некоторых изображений. Для других это работает нормально. Однако, несмотря на то, что он не может проанализировать информацию заголовка, используя Windows API, я могу правильно отобразить все изображения, это просто синтаксический анализ информации заголовка встроенного профиля ICC, которая является ошибочной.


Не работает

Используя инструмент exif_tool для отображения информации заголовка профиля ICC для изображения, которое не работает из моего кода, exif_tool правильно возвращает:

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, который не определен (см. Ниже). Кроме того, тег версии анализируется в версии 2.0 (0x02000000), а не в версии v2.1, как показано в выводе exif_tool выше.

enter image description here

Кроме того, послеэтот запрос (в моем коде) для возврата тега ICC 0x64657363 (ProfileDescription) возвращает «opRGB» вместо «Adobe RGB (1998)».

В терминах данных EXIF ​​для этого изображения, цветовое пространствоопределяется как «некалиброванный», а для «R03» задан «индекс взаимодействия», который, как я понимаю, должен интерпретироваться как Adobe RGB.

рабочий


Используя другой JPG со встроенным профилем Adobe RGB (1998), я проверил его через exif_tool, и он отображает:

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, Independent
Device Manufacturer             : none
Device Model                    :
Device Attributes               : Reflective, Glossy, Positive, 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)
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

При использовании OpenColourProfile мой код (который использует Windows API) правильно анализируетинформация заголовка:

enter image description here

После этого запрос (в моем коде) на возвращение тега ICC 0x64657363 (ProfileDescription) правильно возвращает «Adobe 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,
                        NULL,
                        NULL,
                        PROFILE_READ,
                        FILE_SHARE_READ,
                        OPEN_EXISTING,
                        0);*/

                    hProfile = OpenColorProfile(
                            &prof,
                            PROFILE_READ,
                            FILE_SHARE_READ,
                            OPEN_EXISTING);


                    hr = hProfile ? S_OK : E_FAIL;
                    HeapFree(GetProcessHeap(), 0, 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

Я суммировал различия в информации заголовка ICC, представленные exif_tool, которые приводят к тому, что 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.

Другое программное обеспечение для редактирования изображений правильно отображает оба изображения как «Adobe RGB (1998)»

Кажется, что окнаAPI не нравится, когда встроенная информация ICC предназначена для платформы Microsoft (?)

Это может быть вызвано отсутствием «индекса совместимости» (указанного как «R03»). «для изображения, которое не работает, и не указано для изображения, которое работает», но если бы это было так, это может показаться ошибкой в ​​Windows (?)

Может быть, это «AdobeRGB "и" Adobe RGB (1998) "- это два разных профиля, и все остальные программы, которые сообщают о них как" Adobe RGB (1998) ", просто не различают их?

у меня болит голова. Кто-нибудь знает, что здесь происходит?

Приветствия

РЕДАКТИРОВАНИЕ:

Рабочее изображение (Описание профиля = Adobe RGB (1998), когдачитать с помощью Windows API):

enter image description here

Не работает (описание профиля = opRGB при чтении с Windows API): enter image description here

...