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 */
......@@ -44,6 +44,144 @@ static void MSCMS_basename( LPCWSTR path, LPWSTR name )
lstrcpyW( name, &path[i] );
}
#ifdef HAVE_LCMS_H
static BOOL MSCMS_cpu_is_little_endian()
{
long l = 1;
void *p = &l;
char b = *(char *)p;
return b ? TRUE : FALSE;
}
static void MSCMS_endian_swap16( BYTE *byte )
{
BYTE tmp;
tmp = byte[0];
byte[0] = byte[1];
byte[1] = tmp;
}
static void MSCMS_endian_swap32( BYTE *byte )
{
BYTE tmp1, tmp2;
tmp1 = *byte++;
tmp2 = *byte++;
*(byte - 1) = *byte;
*byte++ = tmp2;
*(byte - 3) = *byte;
*byte = tmp1;
}
static void MSCMS_adjust_endianess32( BYTE *byte )
{
if (MSCMS_cpu_is_little_endian())
MSCMS_endian_swap32( byte );
}
static void MSCMS_get_profile_header( icProfile *iccprofile, PROFILEHEADER *header )
{
memcpy( header, iccprofile, sizeof(PROFILEHEADER) );
/* ICC format is big-endian, swap bytes if necessary */
if (MSCMS_cpu_is_little_endian())
{
MSCMS_endian_swap32( (BYTE *)&header->phSize );
MSCMS_endian_swap32( (BYTE *)&header->phCMMType );
MSCMS_endian_swap32( (BYTE *)&header->phVersion );
MSCMS_endian_swap32( (BYTE *)&header->phClass );
MSCMS_endian_swap32( (BYTE *)&header->phDataColorSpace );
MSCMS_endian_swap32( (BYTE *)&header->phConnectionSpace );
MSCMS_endian_swap32( (BYTE *)&header->phDateTime[0] );
MSCMS_endian_swap32( (BYTE *)&header->phDateTime[1] );
MSCMS_endian_swap32( (BYTE *)&header->phDateTime[2] );
MSCMS_endian_swap32( (BYTE *)&header->phSignature );
MSCMS_endian_swap32( (BYTE *)&header->phPlatform );
MSCMS_endian_swap32( (BYTE *)&header->phProfileFlags );
MSCMS_endian_swap32( (BYTE *)&header->phManufacturer );
MSCMS_endian_swap32( (BYTE *)&header->phModel );
MSCMS_endian_swap32( (BYTE *)&header->phAttributes[0] );
MSCMS_endian_swap32( (BYTE *)&header->phAttributes[1] );
MSCMS_endian_swap32( (BYTE *)&header->phRenderingIntent );
MSCMS_endian_swap32( (BYTE *)&header->phIlluminant );
MSCMS_endian_swap32( (BYTE *)&header->phCreator );
}
}
static void MSCMS_set_profile_header( icProfile *iccprofile, PROFILEHEADER *header )
{
icHeader *iccheader = (icHeader *)iccprofile;
memcpy( iccprofile, header, sizeof(PROFILEHEADER) );
/* ICC format is big-endian, swap bytes if necessary */
if (MSCMS_cpu_is_little_endian())
{
MSCMS_endian_swap32( (BYTE *)&iccheader->size );
MSCMS_endian_swap32( (BYTE *)&iccheader->cmmId );
MSCMS_endian_swap32( (BYTE *)&iccheader->version );
MSCMS_endian_swap32( (BYTE *)&iccheader->deviceClass );
MSCMS_endian_swap32( (BYTE *)&iccheader->colorSpace );
MSCMS_endian_swap32( (BYTE *)&iccheader->pcs );
MSCMS_endian_swap16( (BYTE *)&iccheader->date.year );
MSCMS_endian_swap16( (BYTE *)&iccheader->date.month );
MSCMS_endian_swap16( (BYTE *)&iccheader->date.day );
MSCMS_endian_swap16( (BYTE *)&iccheader->date.hours );
MSCMS_endian_swap16( (BYTE *)&iccheader->date.minutes );
MSCMS_endian_swap16( (BYTE *)&iccheader->date.seconds );
MSCMS_endian_swap32( (BYTE *)&iccheader->magic );
MSCMS_endian_swap32( (BYTE *)&iccheader->platform );
MSCMS_endian_swap32( (BYTE *)&iccheader->flags );
MSCMS_endian_swap32( (BYTE *)&iccheader->manufacturer );
MSCMS_endian_swap32( (BYTE *)&iccheader->model );
MSCMS_endian_swap32( (BYTE *)&iccheader->attributes[0] );
MSCMS_endian_swap32( (BYTE *)&iccheader->attributes[1] );
MSCMS_endian_swap32( (BYTE *)&iccheader->renderingIntent );
MSCMS_endian_swap32( (BYTE *)&iccheader->illuminant );
MSCMS_endian_swap32( (BYTE *)&iccheader->creator );
}
}
static DWORD MSCMS_get_tag_count( icProfile *iccprofile )
{
DWORD count = iccprofile->count;
MSCMS_adjust_endianess32( (BYTE *)&count );
return count;
}
static void MSCMS_get_tag_by_index( icProfile *iccprofile, DWORD index, icTag *tag )
{
icTag *tmp = (icTag *)&iccprofile->data + (index * sizeof(icTag));
tag->sig = tmp->sig;
tag->offset = tmp->offset;
tag->size = tmp->size;
MSCMS_adjust_endianess32( (BYTE *)&tag->sig );
MSCMS_adjust_endianess32( (BYTE *)&tag->offset );
MSCMS_adjust_endianess32( (BYTE *)&tag->size );
}
static void MSCMS_get_tag_data( icProfile *iccprofile, icTag *tag, DWORD offset, void *buffer )
{
memcpy( buffer, (char *)iccprofile + tag->offset + offset, tag->size - offset );
}
#endif /* HAVE_LCMS_H */
WINE_DEFAULT_DEBUG_CHANNEL(mscms);
/******************************************************************************
......@@ -117,6 +255,43 @@ BOOL WINAPI GetColorDirectoryW( PCWSTR machine, PWSTR buffer, PDWORD size )
return FALSE;
}
BOOL WINAPI GetColorProfileElement( HPROFILE profile, TAGTYPE type, DWORD offset, PDWORD size,
PVOID buffer, PBOOL ref )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS_H
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
DWORD i, count;
icTag tag;
TRACE( "( %p, 0x%08lx, %ld, %p, %p, %p )\n", profile, type, offset, size, buffer, ref );
if (!iccprofile || !ref) return FALSE;
count = MSCMS_get_tag_count( iccprofile );
for (i = 0; i < count; i++)
{
MSCMS_get_tag_by_index( iccprofile, i, &tag );
if (tag.sig == type)
{
if ((tag.size - offset) > *size || !buffer)
{
*size = (tag.size - offset);
return FALSE;
}
MSCMS_get_tag_data( iccprofile, &tag, offset, buffer );
*ref = FALSE; /* FIXME: calculate properly */
return TRUE;
}
}
#endif /* HAVE_LCMS_H */
return ret;
}
/******************************************************************************
* GetColorProfileElementTag [MSCMS.@]
*
......@@ -135,20 +310,69 @@ BOOL WINAPI GetColorDirectoryW( PCWSTR machine, PWSTR buffer, PDWORD size )
* The tag table index starts at 1.
* Use GetCountColorProfileElements to retrieve a count of tagged elements.
*/
BOOL WINAPI GetColorProfileElementTag( HPROFILE profile, DWORD index, PTAGTYPE tag )
BOOL WINAPI GetColorProfileElementTag( HPROFILE profile, DWORD index, PTAGTYPE type )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS_H
LCMSICCPROFILE *cmsprofile = (LCMSICCPROFILE *)MSCMS_hprofile2cmsprofile( profile );
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
DWORD count;
icTag tag;
TRACE( "( %p, %ld, %p )\n", profile, index, tag );
TRACE( "( %p, %ld, %p )\n", profile, index, type );
if (cmsprofile)
if (!iccprofile) return FALSE;
count = MSCMS_get_tag_count( iccprofile );
if (index > count) return FALSE;
MSCMS_get_tag_by_index( iccprofile, index - 1, &tag );
*type = tag.sig;
ret = TRUE;
#endif /* HAVE_LCMS_H */
return ret;
}
BOOL WINAPI GetColorProfileFromHandle( HPROFILE profile, PBYTE buffer, PDWORD size )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS_H
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
PROFILEHEADER header;
TRACE( "( %p, %p, %p )\n", profile, buffer, size );
if (!iccprofile) return FALSE;
MSCMS_get_profile_header( profile, &header );
if (!buffer || header.phSize > *size)
{
*tag = cmsprofile->TagNames[index - 1];
ret = TRUE;
*size = header.phSize;
return FALSE;
}
/* FIXME: no endian conversion */
memcpy( buffer, iccprofile, header.phSize );
ret = TRUE;
#endif /* HAVE_LCMS_H */
return ret;
}
BOOL WINAPI GetColorProfileHeader( HPROFILE profile, PPROFILEHEADER header )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS_H
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
TRACE( "( %p, %p )\n", profile, header );
if (!iccprofile || !header) return FALSE;
MSCMS_get_profile_header( iccprofile, header );
return TRUE;
#endif /* HAVE_LCMS_H */
return ret;
}
......@@ -171,15 +395,13 @@ BOOL WINAPI GetCountColorProfileElements( HPROFILE profile, PDWORD count )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS_H
LCMSICCPROFILE *cmsprofile = (LCMSICCPROFILE *)MSCMS_hprofile2cmsprofile( profile );
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
TRACE( "( %p, %p )\n", profile, count );
if (cmsprofile)
{
*count = cmsprofile->TagCount;
ret = TRUE;
}
if (!count) return FALSE;
*count = MSCMS_get_tag_count( iccprofile );
ret = TRUE;
#endif /* HAVE_LCMS_H */
return ret;
......@@ -307,6 +529,8 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE profile, TAGTYPE tag, PBOOL prese
TRACE( "( %p, 0x%08lx, %p )\n", profile, tag, present );
if (!present) return FALSE;
#ifdef HAVE_LCMS_H
ret = cmsIsTag( MSCMS_hprofile2cmsprofile( profile ), tag );
......@@ -330,9 +554,34 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE profile, TAGTYPE tag, PBOOL prese
*/
BOOL WINAPI IsColorProfileValid( HPROFILE profile, PBOOL valid )
{
FIXME( "( %p, %p ) stub\n", profile, valid );
BOOL ret = FALSE;
#ifdef HAVE_LCMS_H
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
TRACE( "( %p, %p )\n", profile, valid );
return *valid = TRUE;
if (!valid) return FALSE;
if (iccprofile) return *valid = TRUE;
#endif /* HAVE_LCMS_H */
return ret;
}
BOOL WINAPI SetColorProfileHeader( HPROFILE profile, PPROFILEHEADER header )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS_H
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
TRACE( "( %p, %p )\n", profile, header );
if (!iccprofile || !header) return FALSE;
MSCMS_set_profile_header( iccprofile, header );
return TRUE;
#endif /* HAVE_LCMS_H */
return ret;
}
/******************************************************************************
......@@ -385,8 +634,7 @@ BOOL WINAPI UninstallColorProfileW( PCWSTR machine, PCWSTR profile, BOOL delete
if (machine || !profile) return FALSE;
if (delete)
return DeleteFileW( profile );
if (delete) return DeleteFileW( profile );
return TRUE;
}
......@@ -450,12 +698,15 @@ HPROFILE WINAPI OpenColorProfileA( PPROFILE profile, DWORD access, DWORD sharing
* Values for sharing: 0 (no sharing), FILE_SHARE_READ and/or FILE_SHARE_WRITE.
* Values for creation: one of CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING,
* OPEN_ALWAYS, TRUNCATE_EXISTING.
* Sharing and creation flags are ignored for memory based profiles.
*/
HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation )
{
#ifdef HAVE_LCMS_H
cmsHPROFILE cmsprofile = NULL;
icProfile *iccprofile = NULL;
HANDLE handle = NULL;
DWORD size;
TRACE( "( %p, 0x%08lx, 0x%08lx, 0x%08lx )\n", profile, access, sharing, creation );
......@@ -463,15 +714,19 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing
if (profile->dwType & PROFILE_MEMBUFFER)
{
FIXME( "Memory based profile not yet supported.\n" ); return NULL;
FIXME( "access flags not implemented for memory based profiles\n" );
iccprofile = profile->pProfileData;
size = profile->cbDataSize;
cmsprofile = cmsOpenProfileFromMem( iccprofile, size );
}
if (profile->dwType & PROFILE_FILENAME)
{
char *unixname;
DWORD flags = 0;
DWORD read, flags = 0;
TRACE("profile file: %s\n", debugstr_w( (WCHAR *)profile->pProfileData ));
TRACE( "profile file: %s\n", debugstr_w( (WCHAR *)profile->pProfileData ) );
if (access & PROFILE_READ) flags = GENERIC_READ;
if (access & PROFILE_READWRITE) flags = GENERIC_READ|GENERIC_WRITE;
......@@ -479,18 +734,41 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing
if (!flags) return NULL;
handle = CreateFileW( profile->pProfileData, flags, sharing, NULL, creation, 0, NULL );
if (handle == INVALID_HANDLE_VALUE) return NULL;
if (handle == INVALID_HANDLE_VALUE)
{
WARN( "Unable to open color profile\n" );
return NULL;
}
unixname = wine_get_unix_file_name( (WCHAR *)profile->pProfileData );
if ((size = GetFileSize( handle, NULL )) == INVALID_FILE_SIZE)
{
ERR( "Unable to retrieve size of color profile\n" );
CloseHandle( handle );
return NULL;
}
if (unixname)
iccprofile = (icProfile *)HeapAlloc( GetProcessHeap(), 0, size );
if (!iccprofile)
{
cmsprofile = cmsOpenProfileFromFile( unixname, flags & GENERIC_READ ? "r" : "w" );
HeapFree( GetProcessHeap(), 0, unixname );
ERR( "Unable to allocate memory for color profile\n" );
CloseHandle( handle );
return NULL;
}
if (!ReadFile( handle, iccprofile, size, &read, NULL ) || read != size)
{
ERR( "Unable to read color profile\n" );
CloseHandle( handle );
HeapFree( GetProcessHeap, 0, iccprofile );
return NULL;
}
cmsprofile = cmsOpenProfileFromMem( iccprofile, size );
}
if (cmsprofile) return MSCMS_create_hprofile_handle( handle, cmsprofile );
if (cmsprofile)
return MSCMS_create_hprofile_handle( handle, iccprofile, cmsprofile );
#endif /* HAVE_LCMS_H */
return NULL;
......@@ -510,16 +788,18 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing
*/
BOOL WINAPI CloseColorProfile( HPROFILE profile )
{
BOOL ret1, ret2 = FALSE;
BOOL ret = FALSE;
TRACE( "( %p )\n", profile );
#ifdef HAVE_LCMS_H
ret1 = cmsCloseProfile( MSCMS_hprofile2cmsprofile( profile ) );
ret2 = CloseHandle( MSCMS_hprofile2handle( profile ) );
ret = cmsCloseProfile( MSCMS_hprofile2cmsprofile( profile ) );
HeapFree( GetProcessHeap(), 0, MSCMS_hprofile2iccprofile( profile ) );
CloseHandle( MSCMS_hprofile2handle( profile ) );
MSCMS_destroy_hprofile_handle( profile );
#endif /* HAVE_LCMS_H */
return ret1 && ret2;
return ret;
}
......@@ -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