Commit 7c98f011 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

Infrastructure for handling ICC profiles.

Always load color profiles into memory. Implement and test GetColorProfileElement and GetColorProfileHeader. Implement GetColorProfileFromHandle and SetColorProfileHeader.
parent 880bc9ce
......@@ -41,15 +41,16 @@ static CRITICAL_SECTION_DEBUG MSCMS_handle_cs_debug =
};
static CRITICAL_SECTION MSCMS_handle_cs = { &MSCMS_handle_cs_debug, -1, 0, 0, 0, 0 };
/* A simple structure to tie together Windows file handles and lcms color
* profile handles. Windows color profile handles are built from indexes
* into an array of these structures. The 'file' field is set to NULL in
* case of a memory based profile
/* A simple structure to tie together a pointer to an icc profile, an lcms
* color profile handle and a Windows file handle. Windows color profile
* handles are built from indexes into an array of these structures. If
* the profile is memory based the file handle field is NULL.
*/
struct handlemap
{
HANDLE file;
icProfile *iccprofile;
cmsHPROFILE cmsprofile;
};
......@@ -57,12 +58,50 @@ struct handlemap
static struct handlemap handlemaptable[CMSMAXHANDLES];
HPROFILE MSCMS_handle2hprofile( HANDLE file )
{
HPROFILE profile = NULL;
unsigned int i;
if (!file) return NULL;
EnterCriticalSection( &MSCMS_handle_cs );
for (i = 0; i <= CMSMAXHANDLES; i++)
{
if (handlemaptable[i].file == file)
{
profile = (HPROFILE)(i + 1); goto out;
}
}
out:
LeaveCriticalSection( &MSCMS_handle_cs );
return profile;
}
HANDLE MSCMS_hprofile2handle( HPROFILE profile )
{
HANDLE file;
unsigned int i;
EnterCriticalSection( &MSCMS_handle_cs );
i = (unsigned int)profile - 1;
file = handlemaptable[i].file;
LeaveCriticalSection( &MSCMS_handle_cs );
return file;
}
HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile )
{
HPROFILE ret = NULL;
HPROFILE profile = NULL;
unsigned int i;
if (!cmsprofile) return ret;
if (!cmsprofile) return NULL;
EnterCriticalSection( &MSCMS_handle_cs );
......@@ -70,70 +109,94 @@ HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile )
{
if (handlemaptable[i].cmsprofile == cmsprofile)
{
ret = (HPROFILE)(i + 1); goto out;
profile = (HPROFILE)(i + 1); goto out;
}
}
out:
LeaveCriticalSection( &MSCMS_handle_cs );
return ret;
return profile;
}
cmsHPROFILE MSCMS_hprofile2cmsprofile( HPROFILE profile )
{
HANDLE ret;
cmsHPROFILE cmshprofile;
unsigned int i;
EnterCriticalSection( &MSCMS_handle_cs );
i = (unsigned int)profile - 1;
ret = handlemaptable[i].cmsprofile;
cmshprofile = handlemaptable[i].cmsprofile;
LeaveCriticalSection( &MSCMS_handle_cs );
return ret;
return cmshprofile;
}
HANDLE MSCMS_hprofile2handle( HPROFILE profile )
HPROFILE MSCMS_iccprofile2hprofile( icProfile *iccprofile )
{
HPROFILE profile = NULL;
unsigned int i;
if (!iccprofile) return NULL;
EnterCriticalSection( &MSCMS_handle_cs );
for (i = 0; i <= CMSMAXHANDLES; i++)
{
if (handlemaptable[i].iccprofile == iccprofile)
{
profile = (HPROFILE)(i + 1); goto out;
}
}
out:
LeaveCriticalSection( &MSCMS_handle_cs );
return profile;
}
icProfile *MSCMS_hprofile2iccprofile( HPROFILE profile )
{
HANDLE ret;
icProfile *iccprofile;
unsigned int i;
EnterCriticalSection( &MSCMS_handle_cs );
i = (unsigned int)profile - 1;
ret = handlemaptable[i].file;
iccprofile = handlemaptable[i].iccprofile;
LeaveCriticalSection( &MSCMS_handle_cs );
return ret;
return iccprofile;
}
HPROFILE MSCMS_create_hprofile_handle( HANDLE file, cmsHPROFILE cmsprofile )
HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile, cmsHPROFILE cmsprofile )
{
HPROFILE ret = NULL;
HPROFILE profile = NULL;
unsigned int i;
if (!cmsprofile) return ret;
if (!cmsprofile || !iccprofile) return NULL;
EnterCriticalSection( &MSCMS_handle_cs );
for (i = 0; i <= CMSMAXHANDLES; i++)
{
if (handlemaptable[i].cmsprofile == 0)
if (handlemaptable[i].iccprofile == 0)
{
handlemaptable[i].file = file;
handlemaptable[i].iccprofile = iccprofile;
handlemaptable[i].cmsprofile = cmsprofile;
ret = (HPROFILE)(i + 1); goto out;
profile = (HPROFILE)(i + 1); goto out;
}
}
out:
LeaveCriticalSection( &MSCMS_handle_cs );
return ret;
return profile;
}
void MSCMS_destroy_hprofile_handle( HPROFILE profile )
......
......@@ -20,10 +20,10 @@
@ stub GetCMMInfo
@ stdcall GetColorDirectoryA(ptr ptr long)
@ stdcall GetColorDirectoryW(ptr ptr long)
@ stub GetColorProfileElement
@ stdcall GetColorProfileElement(ptr long long ptr ptr ptr)
@ stdcall GetColorProfileElementTag(ptr long ptr)
@ stub GetColorProfileFromHandle
@ stub GetColorProfileHeader
@ stdcall GetColorProfileFromHandle(ptr ptr ptr)
@ stdcall GetColorProfileHeader(ptr ptr)
@ stdcall GetCountColorProfileElements(ptr long)
@ stub GetNamedProfileInfo
@ stub GetPS2ColorRenderingDictionary
......@@ -49,7 +49,7 @@
@ stub SetColorProfileElement
@ stub SetColorProfileElementReference
@ stub SetColorProfileElementSize
@ stub SetColorProfileHeader
@ stdcall SetColorProfileHeader(ptr ptr)
@ stub SetStandardColorSpaceProfileA
@ stub SetStandardColorSpaceProfileW
@ stub SpoolerCopyFileEvent
......
......@@ -25,7 +25,7 @@
#ifdef HAVE_LCMS_H
/* These basic Windows types are defined in lcms.h when compiling on
* a non-Windows platforms (why?), so they would normally not conflict
* a non-Windows platform (why?), so they would normally not conflict
* with anything included earlier. But since we are building Wine they
* most certainly will have been defined before we include lcms.h.
* The preprocessor comes to the rescue.
......@@ -68,11 +68,14 @@
#define DWORD DWORD
#define LPDWORD LPDWORD
extern HPROFILE MSCMS_handle2hprofile( HANDLE file );
extern HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile );
extern cmsHPROFILE MSCMS_hprofile2cmsprofile( HPROFILE profile );
extern HPROFILE MSCMS_iccprofile2hprofile( icProfile *iccprofile );
extern HANDLE MSCMS_hprofile2handle( HPROFILE profile );
extern cmsHPROFILE MSCMS_hprofile2cmsprofile( HPROFILE profile );
extern icProfile *MSCMS_hprofile2iccprofile( HPROFILE profile );
extern HPROFILE MSCMS_create_hprofile_handle( HANDLE file, cmsHPROFILE cmsprofile );
extern HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile, cmsHPROFILE cmsprofile );
extern void MSCMS_destroy_hprofile_handle( HPROFILE profile );
#endif /* HAVE_LCMS_H */
......@@ -144,6 +144,46 @@ static void test_GetColorDirectoryW()
ok( ret, "GetColorDirectoryW() failed (%ld)\n", GetLastError() );
}
static void test_GetColorProfileElement()
{
if (standardprofile)
{
PROFILE profile;
HPROFILE handle;
BOOL ret, ref;
DWORD size;
TAGTYPE tag = 0x63707274; /* 'cprt' */
static char buffer[51];
static char expect[] =
{ 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70,
0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20,
0x31, 0x39, 0x39, 0x38, 0x20, 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74,
0x74, 0x2d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43,
0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x00 };
profile.dwType = PROFILE_FILENAME;
profile.pProfileData = standardprofile;
profile.cbDataSize = strlen(standardprofile);
handle = OpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
size = 0;
ret = GetColorProfileElement( handle, tag, 0, &size, NULL, &ref );
ok( !ret, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
size = sizeof(buffer);
ret = GetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
ok( ret, "GetColorProfileElement() failed (%ld)\n", GetLastError() );
ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected tag data\n" );
CloseColorProfile( handle );
}
}
static void test_GetColorProfileElementTag()
{
if (standardprofile)
......@@ -162,7 +202,39 @@ static void test_GetColorProfileElementTag()
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
ret = GetColorProfileElementTag( handle, index, &tag );
ok( ret && tag == expect, "GetColorProfileElementTag() failed (%ld)\n", GetLastError() );
ok( ret && tag == expect, "GetColorProfileElementTag() failed (%ld) 0x%08lx\n",
GetLastError(), tag );
CloseColorProfile( handle );
}
}
static void test_GetColorProfileHeader()
{
if (testprofile)
{
PROFILE profile;
HPROFILE handle;
BOOL ret;
static PROFILEHEADER header;
static PROFILEHEADER expect =
{ 0x00000c48, 0x4c696e6f, 0x02100000, 0x6d6e7472, 0x52474220, 0x58595a20,
{ 0x07ce0002, 0x00090006, 0x61637370 }, 0x61637370, 0x4d534654, 0x00000000,
0x49454320, 0x73524742, { 0x00000000, 0x00000000 }, 0x00000000, { 0x0000f6d6,
0x00000100, 0x2dd30000 }, 0x48502020 };
profile.dwType = PROFILE_FILENAME;
profile.pProfileData = testprofile;
profile.cbDataSize = strlen(testprofile);
handle = OpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
ret = GetColorProfileHeader( handle, &header );
ok( ret, "GetColorProfileHeader() failed (%ld)\n", GetLastError() );
ok( memcmp( &header, &expect, FIELD_OFFSET(PROFILEHEADER, phReserved) ),
"Unexpected header data\n" );
CloseColorProfile( handle );
}
......@@ -549,7 +621,10 @@ START_TEST(profile)
test_GetColorDirectoryA();
test_GetColorDirectoryW();
test_GetColorProfileElement();
test_GetColorProfileElementTag();
test_GetColorProfileHeader();
test_GetCountColorProfileElements();
test_InstallColorProfileA();
......
......@@ -87,7 +87,7 @@ typedef struct tagPROFILEHEADER
DWORD phProfileFlags;
DWORD phManufacturer;
DWORD phModel;
DWORD phAttributes;
DWORD phAttributes[2];
DWORD phRenderingIntent;
CIEXYZ phIlluminant;
DWORD phCreator;
......@@ -160,6 +160,7 @@ BOOL WINAPI GetColorDirectoryW(PCWSTR,PWSTR,PDWORD);
#define GetColorDirectory WINELIB_NAME_AW(GetColorDirectory)
BOOL WINAPI GetColorProfileElement(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID,PBOOL);
BOOL WINAPI GetColorProfileElementTag(HPROFILE,DWORD,PTAGTYPE);
BOOL WINAPI GetColorProfileHeader(HPROFILE,PPROFILEHEADER);
BOOL WINAPI GetCountColorProfileElements(HPROFILE,PDWORD);
BOOL WINAPI GetStandardColorSpaceProfileA(PCSTR,DWORD,PSTR,PDWORD);
BOOL WINAPI GetStandardColorSpaceProfileW(PCWSTR,DWORD,PWSTR,PDWORD);
......@@ -172,6 +173,7 @@ BOOL WINAPI IsColorProfileValid(HPROFILE,PBOOL);
HPROFILE WINAPI OpenColorProfileA(PPROFILE,DWORD,DWORD,DWORD);
HPROFILE WINAPI OpenColorProfileW(PPROFILE,DWORD,DWORD,DWORD);
#define OpenColorProfile WINELIB_NAME_AW(OpenColorProfile)
BOOL WINAPI SetColorProfileHeader(HPROFILE,PPROFILEHEADER);
BOOL WINAPI SetupColorMatchingA(PCOLORMATCHSETUPA);
BOOL WINAPI SetupColorMatchingW(PCOLORMATCHSETUPW);
#define SetupColorMatching WINELIB_NAME_AW(SetupColorMatching)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment