Move ICC profile handling into its own file.

Test GetColorProfileFromHandle and SetColorProfileHeader.
Test and partially implement {G,S}etStandardColorSpaceProfile{A,W}.
Improve existing tests and fix any bugs they revealed.
This commit is contained in:
Hans Leidekker 2004-12-07 14:42:47 +00:00 committed by Alexandre Julliard
parent e7110f0982
commit 8360a3a87e
7 changed files with 524 additions and 197 deletions

View File

@ -3,10 +3,11 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = mscms.dll
IMPORTS = kernel32
IMPORTS = kernel32 ntdll
C_SRCS = \
handle.c \
icc.c \
mscms_main.c \
profile.c

98
dlls/mscms/icc.c Normal file
View File

@ -0,0 +1,98 @@
/*
* MSCMS - Color Management System for Wine
*
* Copyright 2004 Hans Leidekker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wine/debug.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
#include "winternl.h"
#include "icm.h"
#define LCMS_API_FUNCTION(f) extern typeof(f) * p##f;
#include "lcms_api.h"
#undef LCMS_API_FUNCTION
WINE_DEFAULT_DEBUG_CHANNEL(mscms);
#ifdef HAVE_LCMS_H
static inline void MSCMS_adjust_endianess32( ULONG *ptr )
{
#ifndef WORDS_BIGENDIAN
*ptr = RtlUlongByteSwap(*ptr);
#endif
}
void MSCMS_get_profile_header( icProfile *iccprofile, PROFILEHEADER *header )
{
unsigned int i;
memcpy( header, iccprofile, sizeof(PROFILEHEADER) );
/* ICC format is big-endian, swap bytes if necessary */
for (i = 0; i < sizeof(PROFILEHEADER) / sizeof(ULONG); i++)
MSCMS_adjust_endianess32( (ULONG *)header + i );
}
void MSCMS_set_profile_header( icProfile *iccprofile, PROFILEHEADER *header )
{
unsigned int i;
icHeader *iccheader = (icHeader *)iccprofile;
memcpy( iccheader, header, sizeof(icHeader) );
/* ICC format is big-endian, swap bytes if necessary */
for (i = 0; i < sizeof(icHeader) / sizeof(ULONG); i++)
MSCMS_adjust_endianess32( (ULONG *)iccheader + i );
}
DWORD MSCMS_get_tag_count( icProfile *iccprofile )
{
ULONG count = iccprofile->count;
MSCMS_adjust_endianess32( &count );
return count;
}
void MSCMS_get_tag_by_index( icProfile *iccprofile, DWORD index, icTag *tag )
{
icTag *tmp = (icTag *)((char *)&iccprofile->data + index * sizeof(icTag));
tag->sig = tmp->sig;
tag->offset = tmp->offset;
tag->size = tmp->size;
MSCMS_adjust_endianess32( (ULONG *)&tag->sig );
MSCMS_adjust_endianess32( (ULONG *)&tag->offset );
MSCMS_adjust_endianess32( (ULONG *)&tag->size );
}
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 */

View File

@ -50,8 +50,8 @@
@ stub SetColorProfileElementReference
@ stub SetColorProfileElementSize
@ stdcall SetColorProfileHeader(ptr ptr)
@ stub SetStandardColorSpaceProfileA
@ stub SetStandardColorSpaceProfileW
@ stdcall SetStandardColorSpaceProfileA(ptr long ptr)
@ stdcall SetStandardColorSpaceProfileW(ptr long ptr)
@ stub SpoolerCopyFileEvent
@ stub TranslateBitmapBits
@ stub TranslateColors

View File

@ -78,4 +78,10 @@ extern icProfile *MSCMS_hprofile2iccprofile( HPROFILE profile );
extern HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile, cmsHPROFILE cmsprofile );
extern void MSCMS_destroy_hprofile_handle( HPROFILE profile );
extern DWORD MSCMS_get_tag_count( icProfile *iccprofile );
extern void MSCMS_get_tag_by_index( icProfile *iccprofile, DWORD index, icTag *tag );
extern void MSCMS_get_tag_data( icProfile *iccprofile, icTag *tag, DWORD offset, void *buffer );
extern void MSCMS_get_profile_header( icProfile *iccprofile, PROFILEHEADER *header );
extern void MSCMS_set_profile_header( icProfile *iccprofile, PROFILEHEADER *header );
#endif /* HAVE_LCMS_H */

View File

@ -44,143 +44,11 @@ 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 */
static const WCHAR rgbprofile[] =
{ 'c',':','\\','w','i','n','d','o','w','s','\\', 's','y','s','t','e','m','3','2',
'\\','s','p','o','o','l','\\','d','r','i','v','e','r','s',
'\\','c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
WINE_DEFAULT_DEBUG_CHANNEL(mscms);
@ -194,11 +62,20 @@ BOOL WINAPI GetColorDirectoryA( PCSTR machine, PSTR buffer, PDWORD size )
INT len;
LPWSTR bufferW;
BOOL ret = FALSE;
DWORD sizeW = *size * sizeof(WCHAR);
DWORD sizeW;
TRACE( "( %p, %ld )\n", buffer, *size );
TRACE( "( %p, %p )\n", buffer, size );
if (machine || !buffer) return FALSE;
if (machine || !size) return FALSE;
if (!buffer)
{
ret = GetColorDirectoryW( NULL, NULL, &sizeW );
*size = sizeW / sizeof(WCHAR);
return FALSE;
}
sizeW = *size * sizeof(WCHAR);
bufferW = HeapAlloc( GetProcessHeap(), 0, sizeW );
@ -239,15 +116,16 @@ BOOL WINAPI GetColorDirectoryW( PCWSTR machine, PWSTR buffer, PDWORD size )
DWORD len;
TRACE( "( %p, %ld )\n", buffer, *size );
TRACE( "( %p, %p )\n", buffer, size );
if (machine || !buffer) return FALSE;
if (machine || !size) return FALSE;
len = lstrlenW( colordir ) * sizeof(WCHAR);
if (len <= *size)
if (len <= *size && buffer)
{
lstrcpyW( buffer, colordir );
*size = len;
return TRUE;
}
@ -266,7 +144,7 @@ BOOL WINAPI GetColorProfileElement( HPROFILE profile, TAGTYPE type, DWORD offset
TRACE( "( %p, 0x%08lx, %ld, %p, %p, %p )\n", profile, type, offset, size, buffer, ref );
if (!iccprofile || !ref) return FALSE;
if (!iccprofile || !size || !ref) return FALSE;
count = MSCMS_get_tag_count( iccprofile );
for (i = 0; i < count; i++)
@ -295,7 +173,7 @@ BOOL WINAPI GetColorProfileElement( HPROFILE profile, TAGTYPE type, DWORD offset
/******************************************************************************
* GetColorProfileElementTag [MSCMS.@]
*
* Get a tag name from a color profile by index.
* Get a tag from a color profile by index.
*
* PARAMS
* profile [I] Handle to a color profile.
@ -320,10 +198,10 @@ BOOL WINAPI GetColorProfileElementTag( HPROFILE profile, DWORD index, PTAGTYPE t
TRACE( "( %p, %ld, %p )\n", profile, index, type );
if (!iccprofile) return FALSE;
if (!iccprofile || !type) return FALSE;
count = MSCMS_get_tag_count( iccprofile );
if (index > count) return FALSE;
if (index > count || index < 1) return FALSE;
MSCMS_get_tag_by_index( iccprofile, index - 1, &tag );
*type = tag.sig;
@ -343,8 +221,8 @@ BOOL WINAPI GetColorProfileFromHandle( HPROFILE profile, PBYTE buffer, PDWORD si
TRACE( "( %p, %p, %p )\n", profile, buffer, size );
if (!iccprofile) return FALSE;
MSCMS_get_profile_header( profile, &header );
if (!iccprofile || !size) return FALSE;
MSCMS_get_profile_header( iccprofile, &header );
if (!buffer || header.phSize > *size)
{
@ -352,7 +230,7 @@ BOOL WINAPI GetColorProfileFromHandle( HPROFILE profile, PBYTE buffer, PDWORD si
return FALSE;
}
/* FIXME: no endian conversion */
/* No endian conversion needed */
memcpy( buffer, iccprofile, header.phSize );
ret = TRUE;
@ -399,7 +277,7 @@ BOOL WINAPI GetCountColorProfileElements( HPROFILE profile, PDWORD count )
TRACE( "( %p, %p )\n", profile, count );
if (!count) return FALSE;
if (!iccprofile || !count) return FALSE;
*count = MSCMS_get_tag_count( iccprofile );
ret = TRUE;
@ -412,11 +290,20 @@ BOOL WINAPI GetStandardColorSpaceProfileA( PCSTR machine, DWORD id, PSTR profile
INT len;
LPWSTR profileW;
BOOL ret = FALSE;
DWORD sizeW = *size * sizeof(WCHAR);
DWORD sizeW;
TRACE( "( 0x%08lx, %p, %ld )\n", id, profile, *size );
TRACE( "( 0x%08lx, %p, %p )\n", id, profile, size );
if (machine || !profile) return FALSE;
if (machine || !size) return FALSE;
sizeW = *size * sizeof(WCHAR);
if (!profile)
{
ret = GetStandardColorSpaceProfileW( NULL, id, NULL, &sizeW );
*size = sizeW / sizeof(WCHAR);
return FALSE;
}
profileW = HeapAlloc( GetProcessHeap(), 0, sizeW );
@ -438,9 +325,31 @@ BOOL WINAPI GetStandardColorSpaceProfileA( PCSTR machine, DWORD id, PSTR profile
BOOL WINAPI GetStandardColorSpaceProfileW( PCWSTR machine, DWORD id, PWSTR profile, PDWORD size )
{
FIXME( "( %lx, %p, %ld ) stub\n", id, profile, *size );
DWORD len;
return FALSE;
TRACE( "( 0x%08lx, %p, %p )\n", id, profile, size );
if (machine || !size) return FALSE;
switch (id)
{
case 0x52474220: /* 'RGB ' */
len = sizeof( rgbprofile );
if (*size < len || !profile)
{
*size = len;
return TRUE;
}
lstrcpyW( profile, rgbprofile );
break;
default:
return FALSE;
}
return TRUE;
}
/******************************************************************************
@ -526,13 +435,13 @@ BOOL WINAPI InstallColorProfileW( PCWSTR machine, PCWSTR profile )
BOOL WINAPI IsColorProfileTagPresent( HPROFILE profile, TAGTYPE tag, PBOOL present )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS_H
cmsHPROFILE cmsprofile = MSCMS_hprofile2cmsprofile( profile );
TRACE( "( %p, 0x%08lx, %p )\n", profile, tag, present );
if (!present) return FALSE;
#ifdef HAVE_LCMS_H
ret = cmsIsTag( MSCMS_hprofile2cmsprofile( profile ), tag );
if (!cmsprofile || !present) return FALSE;
ret = cmsIsTag( cmsprofile, tag );
#endif /* HAVE_LCMS_H */
return *present = ret;
@ -584,6 +493,20 @@ BOOL WINAPI SetColorProfileHeader( HPROFILE profile, PPROFILEHEADER header )
return ret;
}
BOOL WINAPI SetStandardColorSpaceProfileA( PCSTR machine, DWORD id, PSTR profile )
{
FIXME( "( 0x%08lx, %p ) stub\n", id, profile );
return TRUE;
}
BOOL WINAPI SetStandardColorSpaceProfileW( PCWSTR machine, DWORD id, PWSTR profile )
{
FIXME( "( 0x%08lx, %p ) stub\n", id, profile );
return TRUE;
}
/******************************************************************************
* UninstallColorProfileA [MSCMS.@]
*

View File

@ -32,6 +32,15 @@
static const char machine[] = "dummy";
static const WCHAR machineW[] = { 'd','u','m','m','y',0 };
/* To do any real functionality testing with this suite you need a copy of
* the freely distributable standard RGB color space profile. It's comes
* standard with Windows, but on Wine you probably need to install it yourself
* in one of the locations mentioned below. Here's a link to the profile in
* a self extracting zip file:
*
* http://download.microsoft.com/download/whistler/hwdev1/1.0/wxp/en-us/ColorProfile.exe
*/
/* Two common places to find the standard color space profile */
static const char profile1[] =
"c:\\windows\\system\\color\\srgb color space profile.icm";
@ -48,6 +57,15 @@ static const WCHAR profile2W[] =
'\\','c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
static unsigned char rgbheader[] =
{ 0x48, 0x0c, 0x00, 0x00, 0x6f, 0x6e, 0x69, 0x4c, 0x00, 0x00, 0x10, 0x02,
0x72, 0x74, 0x6e, 0x6d, 0x20, 0x42, 0x47, 0x52, 0x20, 0x5a, 0x59, 0x58,
0x02, 0x00, 0xce, 0x07, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x31, 0x00,
0x70, 0x73, 0x63, 0x61, 0x54, 0x46, 0x53, 0x4d, 0x00, 0x00, 0x00, 0x00,
0x20, 0x43, 0x45, 0x49, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf6, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x2d, 0xd3, 0x00, 0x00, 0x20, 0x20, 0x50, 0x48 };
static LPSTR standardprofile;
static LPWSTR standardprofileW;
@ -80,32 +98,30 @@ static void test_GetColorDirectoryA()
/* Parameter checks */
ret = GetColorDirectoryA( NULL, NULL, NULL );
ok( !ret, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
size = 0;
ret = GetColorDirectoryA( NULL, NULL, &size );
ok( !ret, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
size = 0;
ret = GetColorDirectoryA( NULL, buffer, &size );
ok( !ret, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
size = 1;
ret = GetColorDirectoryA( NULL, buffer, &size );
ok( !ret, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
size = sizeof(buffer);
ret = GetColorDirectoryA( machine, buffer, &size );
ok( !ret, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
ok( !ret && size > 0, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
/* Functional checks */
size = sizeof(buffer);
ret = GetColorDirectoryA( NULL, buffer, &size );
ok( ret, "GetColorDirectoryA() failed (%ld)\n", GetLastError() );
ok( ret && size > 0, "GetColorDirectoryA() failed (%ld)\n", GetLastError() );
}
static void test_GetColorDirectoryW()
@ -116,32 +132,35 @@ static void test_GetColorDirectoryW()
/* Parameter checks */
/* This one crashes win2k
ret = GetColorDirectoryW( NULL, NULL, NULL );
ok( !ret, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
*/
size = 0;
ret = GetColorDirectoryW( NULL, NULL, &size );
ok( !ret, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
size = 0;
ret = GetColorDirectoryW( NULL, buffer, &size );
ok( !ret, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
size = 1;
ret = GetColorDirectoryW( NULL, buffer, &size );
ok( !ret, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
size = sizeof(buffer);
ret = GetColorDirectoryW( machineW, buffer, &size );
ok( !ret, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
ok( !ret && size > 0, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
/* Functional checks */
size = sizeof(buffer);
ret = GetColorDirectoryW( NULL, buffer, &size );
ok( ret, "GetColorDirectoryW() failed (%ld)\n", GetLastError() );
ok( ret && size > 0, "GetColorDirectoryW() failed (%ld)\n", GetLastError() );
ret = GetColorDirectoryW( NULL, buffer, &size );
}
static void test_GetColorProfileElement()
@ -154,7 +173,7 @@ static void test_GetColorProfileElement()
DWORD size;
TAGTYPE tag = 0x63707274; /* 'cprt' */
static char buffer[51];
static char expect[] =
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,
@ -168,15 +187,25 @@ static void test_GetColorProfileElement()
handle = OpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
/* Parameter checks */
ret = GetColorProfileElement( handle, tag, 0, NULL, NULL, &ref );
ok( !ret, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
ret = GetColorProfileElement( handle, tag, 0, &size, NULL, NULL );
ok( !ret, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
size = 0;
ret = GetColorProfileElement( handle, tag, 0, &size, NULL, &ref );
ok( !ret, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
ok( !ret && size > 0, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
size = sizeof(buffer);
/* Functional checks */
ret = GetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
ok( ret, "GetColorProfileElement() failed (%ld)\n", GetLastError() );
ok( ret && size > 0, "GetColorProfileElement() failed (%ld)\n", GetLastError() );
ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected tag data\n" );
@ -201,9 +230,84 @@ static void test_GetColorProfileElementTag()
handle = OpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
/* Parameter checks */
ret = GetColorProfileElementTag( NULL, index, &tag );
ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
ret = GetColorProfileElementTag( handle, 0, &tag );
ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
ret = GetColorProfileElementTag( handle, index, NULL );
ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
ret = GetColorProfileElementTag( handle, 18, NULL );
ok( !ret, "GetColorProfileElementTag() succeeded (%ld)\n", GetLastError() );
/* Functional checks */
ret = GetColorProfileElementTag( handle, index, &tag );
ok( ret && tag == expect, "GetColorProfileElementTag() failed (%ld) 0x%08lx\n",
GetLastError(), tag );
ok( ret && tag == expect, "GetColorProfileElementTag() failed (%ld)\n",
GetLastError() );
CloseColorProfile( handle );
}
}
static void test_GetColorProfileFromHandle()
{
if (testprofile)
{
PROFILE profile;
HPROFILE handle;
DWORD size;
BOOL ret;
static unsigned char expect[] =
{ 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00,
0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00,
0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54,
0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47,
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20 };
unsigned char *buffer;
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() );
buffer = HeapAlloc( GetProcessHeap(), 0, size );
if (buffer)
{
/* Parameter checks */
ret = GetColorProfileFromHandle( NULL, buffer, &size );
ok( !ret, "GetColorProfileFromHandle() succeeded (%ld)\n", GetLastError() );
ret = GetColorProfileFromHandle( handle, buffer, NULL );
ok( !ret, "GetColorProfileFromHandle() succeeded (%ld)\n", GetLastError() );
size = 0;
ret = GetColorProfileFromHandle( handle, NULL, &size );
ok( !ret && size > 0, "GetColorProfileFromHandle() succeeded (%ld)\n",
GetLastError() );
/* Functional checks */
ret = GetColorProfileFromHandle( handle, buffer, &size );
ok( ret && size > 0, "GetColorProfileFromHandle() failed (%ld)\n", GetLastError() );
ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected header data\n" );
HeapFree( GetProcessHeap(), 0, buffer );
}
CloseColorProfile( handle );
}
@ -216,12 +320,7 @@ static void test_GetColorProfileHeader()
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 };
PROFILEHEADER header;
profile.dwType = PROFILE_FILENAME;
profile.pProfileData = testprofile;
@ -230,11 +329,20 @@ static void test_GetColorProfileHeader()
handle = OpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
/* Parameter checks */
ret = GetColorProfileHeader( NULL, &header );
ok( !ret, "GetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
ret = GetColorProfileHeader( handle, NULL );
ok( !ret, "GetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
/* Functional checks */
ret = GetColorProfileHeader( handle, &header );
ok( ret, "GetColorProfileHeader() failed (%ld)\n", GetLastError() );
ok( memcmp( &header, &expect, FIELD_OFFSET(PROFILEHEADER, phReserved) ),
"Unexpected header data\n" );
ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
CloseColorProfile( handle );
}
@ -256,13 +364,106 @@ static void test_GetCountColorProfileElements()
handle = OpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
/* Parameter checks */
ret = GetCountColorProfileElements( NULL, &count );
ok( !ret, "GetCountColorProfileElements() succeeded (%ld)\n",
GetLastError() );
ret = GetCountColorProfileElements( handle, NULL );
ok( !ret, "GetCountColorProfileElements() succeeded (%ld)\n",
GetLastError() );
/* Functional checks */
ret = GetCountColorProfileElements( handle, &count );
ok( ret && count == expect, "GetCountColorProfileElements() failed (%ld)\n", GetLastError() );
ok( ret && count == expect,
"GetCountColorProfileElements() failed (%ld)\n", GetLastError() );
CloseColorProfile( handle );
}
}
static void test_GetStandardColorSpaceProfileA()
{
BOOL ret;
DWORD size;
CHAR profile[MAX_PATH];
/* Parameter checks */
ret = GetStandardColorSpaceProfileA( NULL, 0, profile, NULL );
ok( !ret, "GetStandardColorSpaceProfileA() succeeded (%ld)\n", GetLastError() );
ret = GetStandardColorSpaceProfileA( machine, 0, profile, &size );
ok( !ret, "GetStandardColorSpaceProfileA() succeeded (%ld)\n", GetLastError() );
size = 0;
ret = GetStandardColorSpaceProfileA( NULL, 0, NULL, &size );
ok( !ret, "GetStandardColorSpaceProfileA() succeeded (%ld)\n", GetLastError() );
size = sizeof(profile);
ret = GetStandardColorSpaceProfileA( NULL, 0, profile, &size );
ok( !ret, "GetStandardColorSpaceProfileA() succeeded (%ld)\n", GetLastError() );
/* Functional checks */
if (standardprofile)
{
ret = SetStandardColorSpaceProfileA( NULL, SPACE_RGB, standardprofile );
ok( ret, "SetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
size = sizeof(profile);
ret = GetStandardColorSpaceProfileA( NULL, SPACE_RGB, profile, &size );
ok( ret, "GetStandardColorSpaceProfileA() failed (%ld)\n", GetLastError() );
ok( !lstrcmpiA( (LPSTR)&profile, standardprofile ), "Unexpected profile\n" );
}
}
static void test_GetStandardColorSpaceProfileW()
{
BOOL ret;
DWORD size;
WCHAR profile[MAX_PATH];
/* Parameter checks */
ret = GetStandardColorSpaceProfileW( NULL, 0, profile, NULL );
ok( !ret, "GetStandardColorSpaceProfileW() succeeded (%ld)\n", GetLastError() );
ret = GetStandardColorSpaceProfileW( machineW, 0, profile, &size );
ok( !ret, "GetStandardColorSpaceProfileW() succeeded (%ld)\n", GetLastError() );
size = 0;
ret = GetStandardColorSpaceProfileW( NULL, 0, NULL, &size );
ok( !ret, "GetStandardColorSpaceProfileW() succeeded (%ld)\n", GetLastError() );
size = sizeof(profile);
ret = GetStandardColorSpaceProfileW( NULL, 0, profile, &size );
ok( !ret, "GetStandardColorSpaceProfileW() succeeded (%ld)\n", GetLastError() );
/* Functional checks */
if (standardprofileW)
{
ret = SetStandardColorSpaceProfileW( NULL, SPACE_RGB, standardprofileW );
ok( ret, "SetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
size = sizeof(profile);
ret = GetStandardColorSpaceProfileW( NULL, SPACE_RGB, profile, &size );
ok( ret, "GetStandardColorSpaceProfileW() failed (%ld)\n", GetLastError() );
ok( !lstrcmpiW( (LPWSTR)&profile, standardprofileW ), "Unexpected profile\n" );
}
}
static void test_InstallColorProfileA()
{
BOOL ret;
@ -381,6 +582,8 @@ static void test_IsColorProfileTagPresent()
handle = OpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
/* Parameter checks */
tag = 0;
ret = IsColorProfileTagPresent( handle, tag, &present );
@ -388,6 +591,14 @@ static void test_IsColorProfileTagPresent()
tag = 0x63707274; /* 'cprt' */
ret = IsColorProfileTagPresent( NULL, tag, &present );
ok( !ret, "IsColorProfileTagPresent() succeeded (%ld)\n", GetLastError() );
ret = IsColorProfileTagPresent( handle, tag, NULL );
ok( !ret, "IsColorProfileTagPresent() succeeded (%ld)\n", GetLastError() );
/* Functional checks */
ret = IsColorProfileTagPresent( handle, tag, &present );
ok( ret && present, "IsColorProfileTagPresent() failed (%ld)\n", GetLastError() );
@ -491,6 +702,71 @@ static void test_OpenColorProfileW()
}
}
static void test_SetColorProfileHeader()
{
if (testprofile)
{
PROFILE profile;
HPROFILE handle;
BOOL ret;
PROFILEHEADER header;
profile.dwType = PROFILE_FILENAME;
profile.pProfileData = testprofile;
profile.cbDataSize = strlen(testprofile);
header.phSize = 0x00000c48;
header.phCMMType = 0x4c696e6f;
header.phVersion = 0x02100000;
header.phClass = 0x6d6e7472;
header.phDataColorSpace = 0x52474220;
header.phConnectionSpace = 0x58595a20;
header.phDateTime[0] = 0x07ce0002;
header.phDateTime[1] = 0x00090006;
header.phDateTime[2] = 0x00310000;
header.phSignature = 0x61637370;
header.phPlatform = 0x4d534654;
header.phProfileFlags = 0x00000000;
header.phManufacturer = 0x49454320;
header.phModel = 0x73524742;
header.phAttributes[0] = 0x00000000;
header.phAttributes[1] = 0x00000000;
header.phRenderingIntent = 0x00000000;
header.phIlluminant.ciexyzX = 0x0000f6d6;
header.phIlluminant.ciexyzY = 0x00010000;
header.phIlluminant.ciexyzZ = 0x0000d32d;
header.phCreator = 0x48502020;
/* Parameter checks */
todo_wine
{
handle = OpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
ret = SetColorProfileHeader( handle, &header );
ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() );
CloseColorProfile( handle );
}
handle = OpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING );
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
/* Functional checks */
ret = SetColorProfileHeader( handle, &header );
ok( ret, "SetColorProfileHeader() failed (%ld)\n", GetLastError() );
ret = GetColorProfileHeader( handle, &header );
ok( ret, "GetColorProfileHeader() failed (%ld)\n", GetLastError() );
ok( !memcmp( &header, rgbheader, sizeof(rgbheader) ), "Unexpected header data\n" );
CloseColorProfile( handle );
}
}
static void test_UninstallColorProfileA()
{
BOOL ret;
@ -583,7 +859,7 @@ START_TEST(profile)
WCHAR fileW[MAX_PATH];
/* See if we can find the standard color profile */
handle = CreateFileA( (LPCSTR)&profile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
handle = CreateFileA( profile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
if (handle != INVALID_HANDLE_VALUE)
{
@ -592,7 +868,7 @@ START_TEST(profile)
CloseHandle( handle );
}
handle = CreateFileA( (LPCSTR)&profile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
handle = CreateFileA( profile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
if (handle != INVALID_HANDLE_VALUE)
{
@ -624,9 +900,14 @@ START_TEST(profile)
test_GetColorProfileElement();
test_GetColorProfileElementTag();
test_GetColorProfileFromHandle();
test_GetColorProfileHeader();
test_GetCountColorProfileElements();
test_GetStandardColorSpaceProfileA();
test_GetStandardColorSpaceProfileW();
test_InstallColorProfileA();
test_InstallColorProfileW();
@ -635,6 +916,8 @@ START_TEST(profile)
test_OpenColorProfileA();
test_OpenColorProfileW();
test_SetColorProfileHeader();
test_UninstallColorProfileA();
test_UninstallColorProfileW();

View File

@ -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 GetColorProfileFromHandle(HPROFILE,PBYTE,PDWORD);
BOOL WINAPI GetColorProfileHeader(HPROFILE,PPROFILEHEADER);
BOOL WINAPI GetCountColorProfileElements(HPROFILE,PDWORD);
BOOL WINAPI GetStandardColorSpaceProfileA(PCSTR,DWORD,PSTR,PDWORD);
@ -174,6 +175,9 @@ 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 SetStandardColorSpaceProfileA(PCSTR,DWORD,PSTR);
BOOL WINAPI SetStandardColorSpaceProfileW(PCWSTR,DWORD,PWSTR);
#define SetStandardColorSpaceProfile WINELIB_NAME_AW(SetStandardColorSpaceProfile)
BOOL WINAPI SetupColorMatchingA(PCOLORMATCHSETUPA);
BOOL WINAPI SetupColorMatchingW(PCOLORMATCHSETUPW);
#define SetupColorMatching WINELIB_NAME_AW(SetupColorMatching)
@ -187,6 +191,18 @@ BOOL WINAPI UninstallColorProfileW(PCWSTR,PCWSTR,BOOL);
#define PROFILE_READ 1
#define PROFILE_READWRITE 2
#define SPACE_XYZ 0x58595A20 /* 'XYZ ' */
#define SPACE_Lab 0x4C616220 /* 'Lab ' */
#define SPACE_Luv 0x4C757620 /* 'Luv ' */
#define SPACE_YCbCr 0x59436272 /* 'YCbr' */
#define SPACE_Yxy 0x59787920 /* 'Yxy ' */
#define SPACE_RGB 0x52474220 /* 'RGB ' */
#define SPACE_GRAY 0x47524159 /* 'GRAY' */
#define SPACE_HSV 0x48535620 /* 'HSV ' */
#define SPACE_HLS 0x484C5320 /* 'HLS ' */
#define SPACE_CMYK 0x434D594B /* 'CMYK' */
#define SPACE_CMY 0x434D5920 /* 'CMY ' */
#ifdef __cplusplus
}
#endif