Implement color profile handles.

Implement OpenColorProfile{A,W} and CloseColorProfile.
Implement GetColorDirectory{A,W} and InstallColorProfile{A,W}.
Implement UninstallColorProfile{A,W}.
Dynamically load liblcms.
Add tests.
oldstable
Hans Leidekker 2004-10-07 19:12:41 +00:00 committed by Alexandre Julliard
parent 493d60fe0f
commit 081b25071a
14 changed files with 1143 additions and 303 deletions

307
configure vendored

File diff suppressed because one or more lines are too long

View File

@ -631,15 +631,6 @@ AC_CHECK_HEADERS(libaudioio.h,
[AUDIOIOLIBS="-laudioio"
AC_DEFINE(HAVE_LIBAUDIOIO, 1, [Define if you have libaudioIO])])])
dnl **** Check for lcms ****
AC_CHECK_HEADERS(lcms.h,
[AC_CHECK_LIB(lcms,cmsOpenProfileFromFile,
[AC_DEFINE(HAVE_LCMS,1,[Define if you have lcms libs and headers])
AC_SUBST(LCMSLIBS,"-llcms")
])
])
dnl **** Check for capi4linux ****
AC_CHECK_HEADERS(capi20.h,[
@ -1047,6 +1038,7 @@ then
WINE_GET_SONAME(jpeg,jpeg_start_decompress)
WINE_GET_SONAME(ungif,DGifOpen)
WINE_GET_SONAME(gif,DGifOpen)
WINE_GET_SONAME(lcms,cmsOpenProfileFromFile)
fi
@ -1131,6 +1123,7 @@ AC_CHECK_HEADERS(\
io.h \
jack/jack.h \
jpeglib.h \
lcms.h \
libio.h \
libutil.h \
link.h \
@ -1619,6 +1612,7 @@ dlls/msacm/msg711/Makefile
dlls/msacm/winemp3/Makefile
dlls/msacm/tests/Makefile
dlls/mscms/Makefile
dlls/mscms/tests/Makefile
dlls/msdmo/Makefile
dlls/mshtml/Makefile
dlls/msi/Makefile

View File

@ -4,10 +4,13 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = mscms.dll
IMPORTS = kernel32
EXTRALIBS = @LCMSLIBS@
C_SRCS = \
mscms_main.c
handle.c \
mscms_main.c \
profile.c
SUBDIRS = tests
@MAKE_DLL_RULES@

154
dlls/mscms/handle.c 100644
View File

@ -0,0 +1,154 @@
/*
* 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 <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "icm.h"
#include "mscms_priv.h"
#ifdef HAVE_LCMS_H
static CRITICAL_SECTION MSCMS_handle_cs;
static CRITICAL_SECTION_DEBUG MSCMS_handle_cs_debug =
{
0, 0, &MSCMS_handle_cs,
{ &MSCMS_handle_cs_debug.ProcessLocksList,
&MSCMS_handle_cs_debug.ProcessLocksList },
0, 0, { 0, (DWORD)(__FILE__ ": MSCMS_handle_cs") }
};
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
*/
struct handlemap
{
HANDLE file;
cmsHPROFILE cmsprofile;
};
#define CMSMAXHANDLES 0x80
static struct handlemap handlemaptable[CMSMAXHANDLES];
HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile )
{
HPROFILE ret = NULL;
unsigned int i;
if (!cmsprofile) return ret;
EnterCriticalSection( &MSCMS_handle_cs );
for (i = 0; i <= CMSMAXHANDLES; i++)
{
if (handlemaptable[i].cmsprofile == cmsprofile)
{
ret = (HPROFILE)(i + 1); goto out;
}
}
out:
LeaveCriticalSection( &MSCMS_handle_cs );
return ret;
}
cmsHPROFILE MSCMS_hprofile2cmsprofile( HPROFILE profile )
{
HANDLE ret;
unsigned int i;
EnterCriticalSection( &MSCMS_handle_cs );
i = (unsigned int)profile - 1;
ret = handlemaptable[i].cmsprofile;
LeaveCriticalSection( &MSCMS_handle_cs );
return ret;
}
HANDLE MSCMS_hprofile2handle( HPROFILE profile )
{
HANDLE ret;
unsigned int i;
EnterCriticalSection( &MSCMS_handle_cs );
i = (unsigned int)profile - 1;
ret = handlemaptable[i].file;
LeaveCriticalSection( &MSCMS_handle_cs );
return ret;
}
HPROFILE MSCMS_create_hprofile_handle( HANDLE file, cmsHPROFILE cmsprofile )
{
HPROFILE ret = NULL;
unsigned int i;
if (!cmsprofile) return ret;
EnterCriticalSection( &MSCMS_handle_cs );
for (i = 0; i <= CMSMAXHANDLES; i++)
{
if (handlemaptable[i].cmsprofile == 0)
{
handlemaptable[i].file = file;
handlemaptable[i].cmsprofile = cmsprofile;
ret = (HPROFILE)(i + 1); goto out;
}
}
out:
LeaveCriticalSection( &MSCMS_handle_cs );
return ret;
}
void MSCMS_destroy_hprofile_handle( HPROFILE profile )
{
unsigned int i;
if (profile)
{
EnterCriticalSection( &MSCMS_handle_cs );
i = (unsigned int)profile - 1;
memset( &handlemaptable[i], 0, sizeof(struct handlemap) );
LeaveCriticalSection( &MSCMS_handle_cs );
}
}
#endif /* HAVE_LCMS_H */

View File

@ -0,0 +1,39 @@
/*
* 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 "mscms_priv.h"
#ifndef LCMS_API_FUNCTION
#error "This file should be included with LCMS_API_FUNCTION defined!"
#endif
#ifdef HAVE_LCMS_H
LCMS_API_FUNCTION(cmsCloseProfile)
LCMS_API_FUNCTION(cmsOpenProfileFromFile)
LCMS_API_FUNCTION(cmsOpenProfileFromMem)
#ifndef LCMS_API_NO_REDEFINE
#define cmsCloseProfile pcmsCloseProfile
#define cmsOpenProfileFromFile pcmsOpenProfileFromFile
#define cmsOpenProfileFromMem pcmsOpenProfileFromMem
#endif /* LCMS_API_NO_REDEFINE */
#endif /* HAVE_LCMS_H */

View File

@ -18,8 +18,8 @@
@ stub EnumColorProfilesW
@ stub GenerateCopyFilePaths
@ stub GetCMMInfo
@ stub GetColorDirectoryA
@ stub GetColorDirectoryW
@ stdcall GetColorDirectoryA(ptr ptr long)
@ stdcall GetColorDirectoryW(ptr ptr long)
@ stub GetColorProfileElement
@ stub GetColorProfileElementTag
@ stub GetColorProfileFromHandle
@ -31,8 +31,8 @@
@ stub GetPS2ColorSpaceArray
@ stub GetStandardColorSpaceProfileA
@ stub GetStandardColorSpaceProfileW
@ stub InstallColorProfileA
@ stub InstallColorProfileW
@ stdcall InstallColorProfileA(ptr ptr)
@ stdcall InstallColorProfileW(ptr ptr)
@ stub InternalGetDeviceConfig
@ stub InternalGetPS2CSAFromLCS
@ stub InternalGetPS2ColorRenderingDictionary
@ -55,7 +55,7 @@
@ stub SpoolerCopyFileEvent
@ stub TranslateBitmapBits
@ stub TranslateColors
@ stub UninstallColorProfileA
@ stub UninstallColorProfileW
@ stdcall UninstallColorProfileA(ptr ptr long)
@ stdcall UninstallColorProfileW(ptr ptr long)
@ stub UnregisterCMMA
@ stub UnregisterCMMW

View File

@ -20,77 +20,113 @@
#include "config.h"
#include "wine/port.h"
#include "wine/debug.h"
#include "wine/library.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "icm.h"
#include "wine/debug.h"
#define LCMS_API_NO_REDEFINE
#define LCMS_API_FUNCTION(f) typeof(f) * p##f;
#include "lcms_api.h"
#undef LCMS_API_FUNCTION
WINE_DEFAULT_DEBUG_CHANNEL(mscms);
#ifdef HAVE_LCMS
/* These basic Windows types are defined in lcms.h when compiling on
* a non-Windows platforms (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.
*/
#define BYTE LCMS_BYTE
#define LPBYTE LCMS_LPBYTE
#define WORD LCMS_WORD
#define LPWORD LCMS_LPWORD
#define DWORD LCMS_DWORD
#define LPDWORD LCMS_LPDWORD
#define BOOL LCMS_BOOL
#define LPSTR LCMS_LPSTR
#define LPVOID LCMS_LPVOID
#undef cdecl
#undef FAR
#undef ZeroMemory
#undef CopyMemory
#undef LOWORD
#undef MAX_PATH
#include <lcms.h>
/* Funny thing is lcms.h defines DWORD as an 'unsigned int' whereas Wine
* defines it as an 'unsigned long'. To avoid compiler warnings we use a
* preprocessor define for DWORD and LPDWORD to get back Wine's orginal
* (typedef) definitions.
*/
#undef DWORD
#undef LPDWORD
#define DWORD DWORD
#define LPDWORD LPDWORD
#ifdef HAVE_LCMS_H
#ifndef SONAME_LIBLCMS
#define SONAME_LIBLCMS "liblcms.so"
#endif
HPROFILE WINAPI OpenColorProfileA( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation )
static void *lcmshandle = NULL;
#endif /* HAVE_LCMS_H */
static BOOL MSCMS_init_lcms()
{
FIXME("( %p, %lx, %lx, %lx ) stub!\n", profile, access, sharing, creation );
#ifdef HAVE_LCMS_H
/* dynamically load lcms if not yet loaded */
if (!lcmshandle)
{
lcmshandle = wine_dlopen( SONAME_LIBLCMS, RTLD_NOW, NULL, 0 );
return NULL;
}
/* We can't really do anything useful without liblcms */
if (!lcmshandle)
{
WINE_MESSAGE(
"Wine cannot find the LittleCMS library. To enable Wine to use color\n"
"management functions please install a version of LittleCMS greater\n"
"than or equal to 1.13.\n"
"http://www.littlecms.com\n" );
HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation )
{
FIXME("( %p, %lx, %lx, %lx ) stub!\n", profile, access, sharing, creation );
return FALSE;
}
}
return NULL;
}
#define LOAD_FUNCPTR(f) \
if ((p##f = wine_dlsym( lcmshandle, #f, NULL, 0 )) == NULL) \
goto sym_not_found;
BOOL WINAPI CloseColorProfile( HPROFILE profile )
{
FIXME("( %p ) stub!\n", profile );
LOAD_FUNCPTR(cmsCloseProfile);
LOAD_FUNCPTR(cmsOpenProfileFromFile);
LOAD_FUNCPTR(cmsOpenProfileFromMem);
#undef LOAD_FUNCPTR
return TRUE;
sym_not_found:
WINE_MESSAGE(
"Wine cannot find certain functions that it needs inside the LittleCMS\n"
"library. To enable Wine to use LittleCMS for color management please\n"
"upgrade liblcms to at least version 1.13.\n"
"http://www.littlecms.com\n" );
wine_dlclose( lcmshandle, NULL, 0 );
lcmshandle = NULL;
return FALSE;
#endif /* HAVE_LCMS_H */
WINE_MESSAGE(
"This version of Wine was compiled without support for color management\n"
"functions. This means many color functions are empty stubs and you should\n"
"expect your application to fail. To enable Wine to use LittleCMS for color\n"
"management please install a liblcms development package version 1.13 or\n"
"higher and rebuild Wine.\n"
"http://www.littlecms.com\n" );
return TRUE;
}
static void MSCMS_deinit_lcms()
{
#ifdef HAVE_LCMS_H
if (lcmshandle)
{
wine_dlclose( lcmshandle, NULL, 0 );
lcmshandle = NULL;
}
#endif /* HAVE_LCMS_H */
}
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
TRACE( "(%p, 0x%08lx, %p)\n", hinst, reason, reserved );
switch (reason)
{
case DLL_PROCESS_ATTACH:
return MSCMS_init_lcms();
case DLL_PROCESS_DETACH:
MSCMS_deinit_lcms();
break;
}
return TRUE;
}

View File

@ -0,0 +1,70 @@
/*
* 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
*/
#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
* 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.
*/
#define BYTE LCMS_BYTE
#define LPBYTE LCMS_LPBYTE
#define WORD LCMS_WORD
#define LPWORD LCMS_LPWORD
#define DWORD LCMS_DWORD
#define LPDWORD LCMS_LPDWORD
#define BOOL LCMS_BOOL
#define LPSTR LCMS_LPSTR
#define LPVOID LCMS_LPVOID
#undef cdecl
#undef FAR
#undef ZeroMemory
#undef CopyMemory
#undef LOWORD
#undef MAX_PATH
#include <lcms.h>
/* Funny thing is lcms.h defines DWORD as an 'unsigned int' whereas Wine
* defines it as an 'unsigned long'. To avoid compiler warnings we use a
* preprocessor define for DWORD and LPDWORD to get back Wine's orginal
* (typedef) definitions.
*/
#undef DWORD
#undef LPDWORD
#define DWORD DWORD
#define LPDWORD LPDWORD
extern HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile );
extern cmsHPROFILE MSCMS_hprofile2cmsprofile( HPROFILE profile );
extern HANDLE MSCMS_hprofile2handle( HPROFILE profile );
extern HPROFILE MSCMS_create_hprofile_handle( HANDLE file, cmsHPROFILE cmsprofile );
extern void MSCMS_destroy_hprofile_handle( HPROFILE profile );
#endif /* HAVE_LCMS_H */

View File

@ -0,0 +1,263 @@
/*
* 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 "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);
BOOL WINAPI GetColorDirectoryA( PCSTR machine, PSTR buffer, PDWORD size )
{
INT len;
LPWSTR bufferW;
BOOL ret = FALSE;
DWORD sizeW = *size * sizeof(WCHAR);
TRACE( "( %p, %ld )\n", buffer, *size );
if (machine || !buffer) return FALSE;
bufferW = HeapAlloc( GetProcessHeap(), 0, sizeW );
if (bufferW)
{
ret = GetColorDirectoryW( NULL, bufferW, &sizeW );
*size = sizeW / sizeof(WCHAR);
if (ret)
{
len = WideCharToMultiByte( CP_ACP, 0, bufferW, *size, buffer, *size, NULL, NULL );
if (!len) ret = FALSE;
}
HeapFree( GetProcessHeap(), 0, bufferW );
}
return ret;
}
BOOL WINAPI GetColorDirectoryW( PCWSTR machine, PWSTR buffer, PDWORD size )
{
/* FIXME: Get this directory from the registry? */
static const WCHAR colordir[] =
{ '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',0 };
DWORD len;
TRACE( "( %p, %ld )\n", buffer, *size );
if (machine || !buffer) return FALSE;
len = lstrlenW( colordir ) * sizeof(WCHAR);
if (len <= *size)
{
lstrcatW( buffer, colordir );
return TRUE;
}
*size = len;
return FALSE;
}
BOOL WINAPI InstallColorProfileA( PCSTR machine, PCSTR profile )
{
UINT len;
LPWSTR profileW;
BOOL ret = FALSE;
TRACE( "( %s )\n", debugstr_a(profile) );
if (machine || !profile) return FALSE;
len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 );
profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if (profileW)
{
MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len );
ret = InstallColorProfileW( NULL, profileW );
HeapFree( GetProcessHeap(), 0, profileW );
}
return ret;
}
BOOL WINAPI InstallColorProfileW( PCWSTR machine, PCWSTR profile )
{
FIXME( "( %s ) stub\n", debugstr_w(profile) );
if (machine || !profile) return FALSE;
return FALSE;
}
BOOL WINAPI UninstallColorProfileA( PCSTR machine, PCSTR profile, BOOL delete )
{
if (machine || !profile) return FALSE;
if (delete)
return DeleteFileA( profile );
return TRUE;
}
BOOL WINAPI UninstallColorProfileW( PCWSTR machine, PCWSTR profile, BOOL delete )
{
if (machine || !profile) return FALSE;
if (delete)
return DeleteFileW( profile );
return TRUE;
}
HPROFILE WINAPI OpenColorProfileA( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation )
{
HPROFILE handle = NULL;
TRACE( "( %p, %lx, %lx, %lx )\n", profile, access, sharing, creation );
if (!profile || !profile->pProfileData) return NULL;
/* No AW conversion needed for memory based profiles */
if (profile->dwType & PROFILE_MEMBUFFER)
return OpenColorProfileW( profile, access, sharing, creation );
if (profile->dwType & PROFILE_FILENAME)
{
UINT len;
PROFILE profileW;
profileW.dwType = profile->dwType;
len = MultiByteToWideChar( CP_ACP, 0, profile->pProfileData, -1, NULL, 0 );
profileW.pProfileData = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if (profileW.pProfileData)
{
profileW.cbDataSize = len * sizeof(WCHAR);
MultiByteToWideChar( CP_ACP, 0, profile->pProfileData, -1, profileW.pProfileData, len );
handle = OpenColorProfileW( &profileW, access, sharing, creation );
HeapFree( GetProcessHeap(), 0, profileW.pProfileData );
}
}
return handle;
}
/******************************************************************************
* OpenColorProfileW [MSCMS.@]
*
* Open a color profile.
*
* PARAMS
* profile [I] Pointer to a color profile structure
* access [I] Desired access
* sharing [I] Sharing mode
* creation [I] Creation mode
*
* RETURNS
* Success: Handle to the opened profile
* Failure: NULL
*
* NOTES
* Values for access: PROFILE_READ or PROFILE_READWRITE
* 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.
*/
HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation )
{
#ifdef HAVE_LCMS_H
cmsHPROFILE cmsprofile = NULL;
HANDLE handle = NULL;
TRACE( "( %p, %lx, %lx, %lx )\n", profile, access, sharing, creation );
if (!profile || !profile->pProfileData) return NULL;
if (profile->dwType & PROFILE_MEMBUFFER)
{
FIXME( "Memory based profile not yet supported.\n" ); return NULL;
}
if (profile->dwType & PROFILE_FILENAME)
{
char *unixname;
DWORD flags = 0;
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;
if (!flags) return NULL;
handle = CreateFileW( profile->pProfileData, flags, sharing, NULL, creation, 0, NULL );
if (handle == INVALID_HANDLE_VALUE) return NULL;
unixname = wine_get_unix_file_name( (WCHAR *)profile->pProfileData );
if (unixname)
{
cmsprofile = cmsOpenProfileFromFile( unixname, flags & GENERIC_READ ? "r" : "w" );
HeapFree( GetProcessHeap(), 0, unixname );
}
}
if (cmsprofile) return MSCMS_create_hprofile_handle( handle, cmsprofile );
#endif /* HAVE_LCMS_H */
return NULL;
}
BOOL WINAPI CloseColorProfile( HPROFILE profile )
{
BOOL ret1, ret2 = FALSE;
TRACE( "( %p )\n", profile );
#ifdef HAVE_LCMS_H
ret1 = cmsCloseProfile( MSCMS_hprofile2cmsprofile( profile ) );
ret2 = CloseHandle( MSCMS_hprofile2handle( profile ) );
MSCMS_destroy_hprofile_handle( profile );
#endif /* HAVE_LCMS_H */
return ret1 && ret2;
}

View File

@ -0,0 +1,3 @@
Makefile
profile.ok
testlist.c

View File

@ -0,0 +1,13 @@
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../../..
SRCDIR = @srcdir@
VPATH = @srcdir@
TESTDLL = mscms.dll
IMPORTS = mscms kernel32
CTESTS = \
profile.c
@MAKE_TEST_RULES@
### Dependencies:

View File

@ -0,0 +1,398 @@
/*
* Tests for color profile functions
*
* 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 <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "wingdi.h"
#include "icm.h"
#include "wine/test.h"
static const char machine[] = "dummy";
static const WCHAR machineW[] = { 'd','u','m','m','y',0 };
/* Two common places to find the standard color space profile */
static const char profile1[] =
"c:\\windows\\system\\color\\srgb color space profile.icm";
static const char profile2[] =
"c:\\windows\\system32\\spool\\drivers\\color\\srgb color space profile.icm";
static const WCHAR profile1W[] =
{ 'c',':','\\','w','i','n','d','o','w','s','\\', 's','y','s','t','e','m',
'\\','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 const WCHAR profile2W[] =
{ '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 };
static LPSTR standardprofile = NULL;
static LPWSTR standardprofileW = NULL;
static LPSTR testprofile = NULL;
static LPWSTR testprofileW = NULL;
static void test_GetColorDirectoryA()
{
BOOL ret;
DWORD size;
char buffer[MAX_PATH];
/* Parameter checks */
size = 0;
ret = GetColorDirectoryA( NULL, NULL, &size );
ok( !ret, "GetColorDirectoryA() succeeded (%ld)\n", GetLastError() );
size = 0;
ret = GetColorDirectoryA( NULL, buffer, &size );
ok( !ret, "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() );
/* Functional checks */
size = sizeof(buffer);
ret = GetColorDirectoryA( NULL, buffer, &size );
ok( ret, "GetColorDirectoryA() failed (%ld)\n", GetLastError() );
}
static void test_GetColorDirectoryW()
{
BOOL ret;
DWORD size;
WCHAR buffer[MAX_PATH];
/* Parameter checks */
size = 0;
ret = GetColorDirectoryW( NULL, NULL, &size );
ok( !ret, "GetColorDirectoryW() succeeded (%ld)\n", GetLastError() );
size = 0;
ret = GetColorDirectoryW( NULL, buffer, &size );
ok( !ret, "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() );
/* Functional checks */
size = sizeof(buffer);
ret = GetColorDirectoryW( NULL, buffer, &size );
ok( ret, "GetColorDirectoryW() failed (%ld)\n", GetLastError() );
}
static void test_InstallColorProfileA()
{
BOOL ret;
/* Parameter checks */
ret = InstallColorProfileA( NULL, NULL );
ok( !ret, "InstallColorProfileA() succeeded (%ld)\n", GetLastError() );
ret = InstallColorProfileA( machine, NULL );
ok( !ret, "InstallColorProfileA() succeeded (%ld)\n", GetLastError() );
ret = InstallColorProfileA( NULL, machine );
ok( !ret, "InstallColorProfileA() failed (%ld)\n", GetLastError() );
if (standardprofile)
{
ret = InstallColorProfileA( NULL, standardprofile );
ok( ret, "InstallColorProfileA() failed (%ld)\n", GetLastError() );
}
/* Functional checks */
if (testprofile)
{
ret = InstallColorProfileA( NULL, testprofile );
ok( ret, "InstallColorProfileA() failed (%ld)\n", GetLastError() );
ret = UninstallColorProfileA( NULL, testprofile, TRUE );
ok( ret, "UninstallColorProfileA() failed (%ld)\n", GetLastError() );
}
}
static void test_InstallColorProfileW()
{
BOOL ret;
/* Parameter checks */
ret = InstallColorProfileW( NULL, NULL );
ok( !ret, "InstallColorProfileW() succeeded (%ld)\n", GetLastError() );
ret = InstallColorProfileW( machineW, NULL );
ok( !ret, "InstallColorProfileW() succeeded (%ld)\n", GetLastError() );
ret = InstallColorProfileW( NULL, machineW );
ok( !ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
if (standardprofileW)
{
ret = InstallColorProfileW( NULL, standardprofileW );
ok( ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
}
/* Functional checks */
if (testprofileW)
{
ret = InstallColorProfileW( NULL, testprofileW );
ok( ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
ret = UninstallColorProfileW( NULL, testprofileW, TRUE );
ok( ret, "UninstallColorProfileW() failed (%ld)\n", GetLastError() );
}
}
static void test_OpenColorProfileA()
{
PROFILE profile;
HPROFILE handle;
profile.dwType = PROFILE_FILENAME;
profile.pProfileData = NULL;
profile.cbDataSize = 0;
/* Parameter checks */
handle = OpenColorProfileA( NULL, 0, 0, 0 );
ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
handle = OpenColorProfileA( &profile, 0, 0, 0 );
ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
handle = OpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
handle = OpenColorProfileA( &profile, PROFILE_READWRITE, 0, 0 );
ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
ok ( !CloseColorProfile( NULL ), "CloseColorProfile() succeeded" );
if (standardprofile)
{
profile.pProfileData = standardprofile;
profile.cbDataSize = strlen(standardprofile);
handle = OpenColorProfileA( &profile, 0, 0, 0 );
ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
handle = OpenColorProfileA( &profile, PROFILE_READ, 0, 0 );
ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
handle = OpenColorProfileA( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
ok( handle == NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
/* Functional checks */
handle = OpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
ok( CloseColorProfile( handle ), "CloseColorProfile() failed (%ld)\n", GetLastError() );
}
}
static void test_OpenColorProfileW()
{
PROFILE profile;
HPROFILE handle;
profile.dwType = PROFILE_FILENAME;
profile.pProfileData = NULL;
profile.cbDataSize = 0;
/* Parameter checks */
handle = OpenColorProfileW( NULL, 0, 0, 0 );
ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
handle = OpenColorProfileW( &profile, 0, 0, 0 );
ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
handle = OpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
handle = OpenColorProfileW( &profile, PROFILE_READWRITE, 0, 0 );
ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
ok ( !CloseColorProfile( NULL ), "CloseColorProfile() succeeded" );
if (standardprofileW)
{
profile.pProfileData = standardprofileW;
profile.cbDataSize = lstrlenW(standardprofileW) * sizeof(WCHAR);
handle = OpenColorProfileW( &profile, 0, 0, 0 );
ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
handle = OpenColorProfileW( &profile, PROFILE_READ, 0, 0 );
ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
handle = OpenColorProfileW( &profile, PROFILE_READ|PROFILE_READWRITE, 0, 0 );
ok( handle == NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
/* Functional checks */
handle = OpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING );
ok( handle != NULL, "OpenColorProfileW() failed (%ld)\n", GetLastError() );
ok( CloseColorProfile( handle ), "CloseColorProfile() failed (%ld)\n", GetLastError() );
}
}
static void test_UninstallColorProfileA()
{
BOOL ret;
/* Parameter checks */
ret = UninstallColorProfileA( NULL, NULL, FALSE );
ok( !ret, "UninstallColorProfileA() succeeded (%ld)\n", GetLastError() );
ret = UninstallColorProfileA( machine, NULL, FALSE );
ok( !ret, "UninstallColorProfileA() succeeded (%ld)\n", GetLastError() );
/* Functional checks */
if (testprofile)
{
ret = InstallColorProfileA( NULL, testprofile );
ok( ret, "InstallColorProfileA() failed (%ld)\n", GetLastError() );
ret = UninstallColorProfileA( NULL, testprofile, TRUE );
ok( ret, "UninstallColorProfileA() failed (%ld)\n", GetLastError() );
}
}
static void test_UninstallColorProfileW()
{
BOOL ret;
/* Parameter checks */
ret = UninstallColorProfileW( NULL, NULL, FALSE );
ok( !ret, "UninstallColorProfileW() succeeded (%ld)\n", GetLastError() );
ret = UninstallColorProfileW( machineW, NULL, FALSE );
ok( !ret, "UninstallColorProfileW() succeeded (%ld)\n", GetLastError() );
/* Functional checks */
if (testprofileW)
{
ret = InstallColorProfileW( NULL, testprofileW );
ok( ret, "InstallColorProfileW() failed (%ld)\n", GetLastError() );
ret = UninstallColorProfileW( NULL, testprofileW, TRUE );
ok( ret, "UninstallColorProfileW() failed (%ld)\n", GetLastError() );
}
}
START_TEST(profile)
{
UINT len;
HANDLE handle;
char path[MAX_PATH], file[MAX_PATH];
WCHAR fileW[MAX_PATH];
/* See if we can find the standard color profile */
handle = CreateFileA( (LPCSTR)&profile1, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
if (handle != INVALID_HANDLE_VALUE)
{
standardprofile = (LPSTR)&profile1;
standardprofileW = (LPWSTR)&profile1W;
CloseHandle( handle );
}
handle = CreateFileA( (LPCSTR)&profile2, 0 , 0, NULL, OPEN_EXISTING, 0, NULL );
if (handle != INVALID_HANDLE_VALUE)
{
standardprofile = (LPSTR)&profile2;
standardprofileW = (LPWSTR)&profile2W;
CloseHandle( handle );
}
/* If found, create a temporary copy for testing purposes */
if (standardprofile && GetTempPath( sizeof(path), path ))
{
if (GetTempFileName( path, "rgb", 0, file ))
{
if (CopyFileA( standardprofile, file, FALSE ))
{
testprofile = (LPSTR)&file;
len = MultiByteToWideChar( CP_ACP, 0, testprofile, -1, NULL, 0 );
MultiByteToWideChar( CP_ACP, 0, testprofile, -1, fileW, len );
testprofileW = (LPWSTR)&fileW;
}
}
}
test_GetColorDirectoryA();
test_GetColorDirectoryW();
test_InstallColorProfileA();
test_InstallColorProfileW();
test_OpenColorProfileA();
test_OpenColorProfileW();
test_UninstallColorProfileA();
test_UninstallColorProfileW();
/* Clean up */
if (testprofile)
DeleteFileA( testprofile );
}

View File

@ -245,9 +245,6 @@
/* Define to 1 if you have the <jpeglib.h> header file. */
#undef HAVE_JPEGLIB_H
/* Define if you have lcms libs and headers */
#undef HAVE_LCMS
/* Define to 1 if you have the <lcms.h> header file. */
#undef HAVE_LCMS_H
@ -905,6 +902,9 @@
/* Define to the soname of the libjpeg library. */
#undef SONAME_LIBJPEG
/* Define to the soname of the liblcms library. */
#undef SONAME_LIBLCMS
/* Define to the soname of the libncurses library. */
#undef SONAME_LIBNCURSES

View File

@ -98,14 +98,30 @@ typedef struct tagPROFILE {
DWORD cbDataSize;
} PROFILE, *PPROFILE, *LPPROFILE;
BOOL WINAPI GetColorDirectoryA(PCSTR,PSTR,PDWORD);
BOOL WINAPI GetColorDirectoryW(PCWSTR,PWSTR,PDWORD);
#define GetColorDirectory WINELIB_NAME_AW(GetColorDirectory)
BOOL WINAPI InstallColorProfileA(PCSTR,PCSTR);
BOOL WINAPI InstallColorProfileW(PCWSTR,PCWSTR);
#define InstallColorProfile WINELIB_NAME_AW(InstallColorProfile)
BOOL WINAPI UninstallColorProfileA(PCSTR,PCSTR,BOOL);
BOOL WINAPI UninstallColorProfileW(PCWSTR,PCWSTR,BOOL);
#define UninstallColorProfile WINELIB_NAME_AW(UninstallColorProfile)
HPROFILE WINAPI OpenColorProfileA(PPROFILE,DWORD,DWORD,DWORD);
HPROFILE WINAPI OpenColorProfileW(PPROFILE,DWORD,DWORD,DWORD);
#define OpenColorProfile WINELIB_NAME_AW(OpenColorProfile)
BOOL WINAPI CloseColorProfile(HPROFILE);
#define PROFILE_FILENAME 1
#define PROFILE_MEMBUFFER 2
#define PROFILE_READ 1
#define PROFILE_READWRITE 2
#ifdef __cplusplus
}
#endif