From a5e361e6b8823b97ba8356e88e80cd302022ded5 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Mon, 21 Feb 2005 18:38:15 +0000 Subject: [PATCH] - Add support for color transform handles. - Implement CreateColorTransform{A,W}, CreateMultiProfileTransform, DeleteColorTransform. - Don't depend on lcms for the implementation of IsColorProfileTagPresent. --- dlls/mscms/Makefile.in | 3 +- dlls/mscms/handle.c | 100 ++++++++++++++++++++++------- dlls/mscms/lcms_api.h | 14 ++-- dlls/mscms/mscms_main.c | 8 ++- dlls/mscms/mscms_priv.h | 4 ++ dlls/mscms/profile.c | 22 +++++-- dlls/mscms/stub.c | 34 +--------- dlls/mscms/transform.c | 138 ++++++++++++++++++++++++++++++++++++++++ include/icm.h | 7 ++ 9 files changed, 260 insertions(+), 70 deletions(-) create mode 100644 dlls/mscms/transform.c diff --git a/dlls/mscms/Makefile.in b/dlls/mscms/Makefile.in index 8853692af10..d93bf47c26c 100644 --- a/dlls/mscms/Makefile.in +++ b/dlls/mscms/Makefile.in @@ -10,7 +10,8 @@ C_SRCS = \ icc.c \ mscms_main.c \ profile.c \ - stub.c + stub.c \ + transform.c RC_SRCS = version.rc diff --git a/dlls/mscms/handle.c b/dlls/mscms/handle.c index 3ef8955e72f..6716d1b7bdd 100644 --- a/dlls/mscms/handle.c +++ b/dlls/mscms/handle.c @@ -1,7 +1,7 @@ /* * MSCMS - Color Management System for Wine * - * Copyright 2004 Hans Leidekker + * Copyright 2004, 2005 Hans Leidekker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -49,7 +49,7 @@ static CRITICAL_SECTION MSCMS_handle_cs = { &MSCMS_handle_cs_debug, -1, 0, 0, 0, * call, i.e. PROFILE_READ or PROFILE_READWRITE. */ -struct handlemap +struct profile { HANDLE file; DWORD access; @@ -57,9 +57,15 @@ struct handlemap cmsHPROFILE cmsprofile; }; +struct transform +{ + cmsHTRANSFORM cmstransform; +}; + #define CMSMAXHANDLES 0x80 -static struct handlemap handlemaptable[CMSMAXHANDLES]; +static struct profile profiletable[CMSMAXHANDLES]; +static struct transform transformtable[CMSMAXHANDLES]; HPROFILE MSCMS_handle2hprofile( HANDLE file ) { @@ -72,7 +78,7 @@ HPROFILE MSCMS_handle2hprofile( HANDLE file ) for (i = 0; i <= CMSMAXHANDLES; i++) { - if (handlemaptable[i].file == file) + if (profiletable[i].file == file) { profile = (HPROFILE)(i + 1); goto out; } @@ -80,7 +86,6 @@ HPROFILE MSCMS_handle2hprofile( HANDLE file ) out: LeaveCriticalSection( &MSCMS_handle_cs ); - return profile; } @@ -92,10 +97,9 @@ HANDLE MSCMS_hprofile2handle( HPROFILE profile ) EnterCriticalSection( &MSCMS_handle_cs ); i = (unsigned int)profile - 1; - file = handlemaptable[i].file; + file = profiletable[i].file; LeaveCriticalSection( &MSCMS_handle_cs ); - return file; } @@ -107,7 +111,7 @@ DWORD MSCMS_hprofile2access( HPROFILE profile ) EnterCriticalSection( &MSCMS_handle_cs ); i = (unsigned int)profile - 1; - access = handlemaptable[i].access; + access = profiletable[i].access; LeaveCriticalSection( &MSCMS_handle_cs ); return access; @@ -124,7 +128,7 @@ HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile ) for (i = 0; i <= CMSMAXHANDLES; i++) { - if (handlemaptable[i].cmsprofile == cmsprofile) + if (profiletable[i].cmsprofile == cmsprofile) { profile = (HPROFILE)(i + 1); goto out; } @@ -132,23 +136,21 @@ HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile ) out: LeaveCriticalSection( &MSCMS_handle_cs ); - return profile; } cmsHPROFILE MSCMS_hprofile2cmsprofile( HPROFILE profile ) { - cmsHPROFILE cmshprofile; + cmsHPROFILE cmsprofile; unsigned int i; EnterCriticalSection( &MSCMS_handle_cs ); i = (unsigned int)profile - 1; - cmshprofile = handlemaptable[i].cmsprofile; + cmsprofile = profiletable[i].cmsprofile; LeaveCriticalSection( &MSCMS_handle_cs ); - - return cmshprofile; + return cmsprofile; } HPROFILE MSCMS_iccprofile2hprofile( icProfile *iccprofile ) @@ -162,7 +164,7 @@ HPROFILE MSCMS_iccprofile2hprofile( icProfile *iccprofile ) for (i = 0; i <= CMSMAXHANDLES; i++) { - if (handlemaptable[i].iccprofile == iccprofile) + if (profiletable[i].iccprofile == iccprofile) { profile = (HPROFILE)(i + 1); goto out; } @@ -170,7 +172,6 @@ HPROFILE MSCMS_iccprofile2hprofile( icProfile *iccprofile ) out: LeaveCriticalSection( &MSCMS_handle_cs ); - return profile; } @@ -182,10 +183,9 @@ icProfile *MSCMS_hprofile2iccprofile( HPROFILE profile ) EnterCriticalSection( &MSCMS_handle_cs ); i = (unsigned int)profile - 1; - iccprofile = handlemaptable[i].iccprofile; + iccprofile = profiletable[i].iccprofile; LeaveCriticalSection( &MSCMS_handle_cs ); - return iccprofile; } @@ -201,12 +201,12 @@ HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile, for (i = 0; i <= CMSMAXHANDLES; i++) { - if (handlemaptable[i].iccprofile == 0) + if (profiletable[i].iccprofile == 0) { - handlemaptable[i].file = file; - handlemaptable[i].access = access; - handlemaptable[i].iccprofile = iccprofile; - handlemaptable[i].cmsprofile = cmsprofile; + profiletable[i].file = file; + profiletable[i].access = access; + profiletable[i].iccprofile = iccprofile; + profiletable[i].cmsprofile = cmsprofile; profile = (HPROFILE)(i + 1); goto out; } @@ -226,7 +226,59 @@ void MSCMS_destroy_hprofile_handle( HPROFILE profile ) EnterCriticalSection( &MSCMS_handle_cs ); i = (unsigned int)profile - 1; - memset( &handlemaptable[i], 0, sizeof(struct handlemap) ); + memset( &profiletable[i], 0, sizeof(struct profile) ); + + LeaveCriticalSection( &MSCMS_handle_cs ); + } +} + +cmsHTRANSFORM MSCMS_htransform2cmstransform( HTRANSFORM transform ) +{ + cmsHTRANSFORM cmstransform; + unsigned int i; + + EnterCriticalSection( &MSCMS_handle_cs ); + + i = (unsigned int)transform - 1; + cmstransform = transformtable[i].cmstransform; + + LeaveCriticalSection( &MSCMS_handle_cs ); + return cmstransform; +} + +HTRANSFORM MSCMS_create_htransform_handle( cmsHTRANSFORM cmstransform ) +{ + HTRANSFORM transform = NULL; + unsigned int i; + + if (!cmstransform) return NULL; + + EnterCriticalSection( &MSCMS_handle_cs ); + + for (i = 0; i <= CMSMAXHANDLES; i++) + { + if (transformtable[i].cmstransform == 0) + { + transformtable[i].cmstransform = cmstransform; + transform = (HTRANSFORM)(i + 1); goto out; + } + } + +out: + LeaveCriticalSection( &MSCMS_handle_cs ); + return transform; +} + +void MSCMS_destroy_htransform_handle( HTRANSFORM transform ) +{ + unsigned int i; + + if (transform) + { + EnterCriticalSection( &MSCMS_handle_cs ); + + i = (unsigned int)transform - 1; + memset( &transformtable[i], 0, sizeof(struct transform) ); LeaveCriticalSection( &MSCMS_handle_cs ); } diff --git a/dlls/mscms/lcms_api.h b/dlls/mscms/lcms_api.h index e35cf396916..f88f59743b8 100644 --- a/dlls/mscms/lcms_api.h +++ b/dlls/mscms/lcms_api.h @@ -1,7 +1,7 @@ /* * MSCMS - Color Management System for Wine * - * Copyright 2004 Hans Leidekker + * Copyright 2004, 2005 Hans Leidekker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,14 +27,18 @@ #ifdef HAVE_LCMS_H LCMS_API_FUNCTION(cmsCloseProfile) -LCMS_API_FUNCTION(cmsIsTag) -LCMS_API_FUNCTION(cmsOpenProfileFromFile) +LCMS_API_FUNCTION(cmsCreate_sRGBProfile) +LCMS_API_FUNCTION(cmsCreateMultiprofileTransform) +LCMS_API_FUNCTION(cmsCreateTransform) +LCMS_API_FUNCTION(cmsDeleteTransform) LCMS_API_FUNCTION(cmsOpenProfileFromMem) #ifndef LCMS_API_NO_REDEFINE #define cmsCloseProfile pcmsCloseProfile -#define cmsIsTag pcmsIsTag -#define cmsOpenProfileFromFile pcmsOpenProfileFromFile +#define cmsCreate_sRGBProfile pcmsCreate_sRGBProfile +#define cmsCreateMultiprofileTransform pcmsCreateMultiprofileTransform +#define cmsCreateTransform pcmsCreateTransform +#define cmsDeleteTransform pcmsDeleteTransform #define cmsOpenProfileFromMem pcmsOpenProfileFromMem #endif /* LCMS_API_NO_REDEFINE */ diff --git a/dlls/mscms/mscms_main.c b/dlls/mscms/mscms_main.c index 97dd4cbabf4..c9eedd2c63b 100644 --- a/dlls/mscms/mscms_main.c +++ b/dlls/mscms/mscms_main.c @@ -1,7 +1,7 @@ /* * MSCMS - Color Management System for Wine * - * Copyright 2004 Hans Leidekker + * Copyright 2004, 2005 Hans Leidekker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -73,8 +73,10 @@ static BOOL MSCMS_init_lcms() goto sym_not_found; LOAD_FUNCPTR(cmsCloseProfile); - LOAD_FUNCPTR(cmsIsTag); - LOAD_FUNCPTR(cmsOpenProfileFromFile); + LOAD_FUNCPTR(cmsCreate_sRGBProfile); + LOAD_FUNCPTR(cmsCreateMultiprofileTransform); + LOAD_FUNCPTR(cmsCreateTransform); + LOAD_FUNCPTR(cmsDeleteTransform); LOAD_FUNCPTR(cmsOpenProfileFromMem); #undef LOAD_FUNCPTR diff --git a/dlls/mscms/mscms_priv.h b/dlls/mscms/mscms_priv.h index ece47fb6824..7f22c5c0ef2 100644 --- a/dlls/mscms/mscms_priv.h +++ b/dlls/mscms/mscms_priv.h @@ -80,6 +80,10 @@ extern HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile cmsHPROFILE cmsprofile, DWORD access ); extern void MSCMS_destroy_hprofile_handle( HPROFILE profile ); +extern cmsHTRANSFORM MSCMS_htransform2cmstransform( HTRANSFORM transform ); +extern HTRANSFORM MSCMS_create_htransform_handle( cmsHTRANSFORM cmstransform ); +extern void MSCMS_destroy_htransform_handle( HTRANSFORM transform ); + 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 ); diff --git a/dlls/mscms/profile.c b/dlls/mscms/profile.c index 45620f7ecf6..45492b12b1d 100644 --- a/dlls/mscms/profile.c +++ b/dlls/mscms/profile.c @@ -491,15 +491,29 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE profile, TAGTYPE type, PBOOL pres { BOOL ret = FALSE; #ifdef HAVE_LCMS_H - cmsHPROFILE cmsprofile = MSCMS_hprofile2cmsprofile( profile ); + icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile ); + DWORD i, count; + icTag tag; TRACE( "( %p, 0x%08lx, %p )\n", profile, type, present ); - if (!cmsprofile || !present) return FALSE; - ret = cmsIsTag( cmsprofile, type ); + if (!iccprofile || !present) 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) + { + *present = ret = TRUE; + break; + } + } #endif /* HAVE_LCMS_H */ - return *present = ret; + return ret; } /****************************************************************************** diff --git a/dlls/mscms/stub.c b/dlls/mscms/stub.c index 9225d293e8a..6a62c5c26f8 100644 --- a/dlls/mscms/stub.c +++ b/dlls/mscms/stub.c @@ -1,7 +1,7 @@ /* * MSCMS - Color Management System for Wine * - * Copyright 2004 Hans Leidekker + * Copyright 2004, 2005 Hans Leidekker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -77,22 +77,6 @@ BOOL WINAPI ConvertIndexToColorName( HPROFILE profile, PDWORD index, PCOLOR_NAME return FALSE; } -HTRANSFORM WINAPI CreateColorTransformA( LPLOGCOLORSPACEA space, HPROFILE dest, HPROFILE target, - DWORD flags ) -{ - FIXME( "( %p, %p, %p, 0x%08lx ) stub\n", space, dest, target, flags ); - - return NULL; -} - -HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest, HPROFILE target, - DWORD flags ) -{ - FIXME( "( %p, %p, %p, 0x%08lx ) stub\n", space, dest, target, flags ); - - return NULL; -} - BOOL WINAPI CreateDeviceLinkProfile( PHPROFILE profiles, DWORD nprofiles, PDWORD intents, DWORD nintents, DWORD flags, PBYTE *data, DWORD index ) { @@ -102,15 +86,6 @@ BOOL WINAPI CreateDeviceLinkProfile( PHPROFILE profiles, DWORD nprofiles, PDWORD return FALSE; } -HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofiles, PDWORD intents, - DWORD nintents, DWORD flags, DWORD index ) -{ - FIXME( "( %p, 0x%08lx, %p, 0x%08lx, 0x%08lx, 0x%08lx ) stub\n", - profiles, nprofiles, intents, nintents, flags, index ); - - return NULL; -} - BOOL WINAPI CreateProfileFromLogColorSpaceA( LPLOGCOLORSPACEA space, PBYTE *buffer ) { FIXME( "( %p, %p ) stub\n", space, buffer ); @@ -125,13 +100,6 @@ BOOL WINAPI CreateProfileFromLogColorSpaceW( LPLOGCOLORSPACEW space, PBYTE *buff return FALSE; } -BOOL WINAPI DeleteColorTransform( HTRANSFORM transform ) -{ - FIXME( "( %p ) stub\n", transform ); - - return TRUE; -} - BOOL WINAPI DisassociateColorProfileFromDeviceA( PCSTR machine, PCSTR profile, PCSTR device ) { FIXME( "( %p, %p, %p ) stub\n", machine, profile, device ); diff --git a/dlls/mscms/transform.c b/dlls/mscms/transform.c new file mode 100644 index 00000000000..234a336c8e6 --- /dev/null +++ b/dlls/mscms/transform.c @@ -0,0 +1,138 @@ +/* + * MSCMS - Color Management System for Wine + * + * Copyright 2005 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 + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "wingdi.h" +#include "winuser.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); + +HTRANSFORM WINAPI CreateColorTransformA( LPLOGCOLORSPACEA space, HPROFILE dest, + HPROFILE target, DWORD flags ) +{ + LOGCOLORSPACEW spaceW; + DWORD len; + + TRACE( "( %p, %p, %p, 0x%08lx )\n", space, dest, target, flags ); + + if (!space || !dest) return FALSE; + + memcpy( &spaceW, space, FIELD_OFFSET(LOGCOLORSPACEA, lcsFilename) ); + spaceW.lcsSize = sizeof(LOGCOLORSPACEW); + + len = MultiByteToWideChar( CP_ACP, 0, space->lcsFilename, -1, NULL, 0 ); + MultiByteToWideChar( CP_ACP, 0, space->lcsFilename, -1, spaceW.lcsFilename, len ); + + return CreateColorTransformW( &spaceW, dest, target, flags ); +} + +HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest, + HPROFILE target, DWORD flags ) +{ + HTRANSFORM ret = NULL; +#ifdef HAVE_LCMS_H + cmsHTRANSFORM cmstransform; + cmsHPROFILE cmsprofiles[3]; + + TRACE( "( %p, %p, %p, 0x%08lx )\n", space, dest, target, flags ); + + if (!space || !dest) return FALSE; + + cmsprofiles[0] = cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */ + cmsprofiles[1] = MSCMS_hprofile2cmsprofile( dest ); + + if (target) + { + cmsprofiles[2] = MSCMS_hprofile2cmsprofile( target ); + cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, 3, TYPE_BGR_8, + TYPE_BGR_8, space->lcsIntent, 0 ); + } + else + { + cmstransform = cmsCreateTransform( cmsprofiles[0], TYPE_BGR_8, cmsprofiles[1], + TYPE_BGR_8, space->lcsIntent, 0 ); + } + + ret = MSCMS_create_htransform_handle( cmstransform ); + +#endif /* HAVE_LCMS_H */ + return ret; +} + +HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofiles, + PDWORD intents, DWORD nintents, DWORD flags, DWORD cmm ) +{ + HTRANSFORM ret = NULL; +#ifdef HAVE_LCMS_H + cmsHPROFILE *cmsprofiles; + cmsHTRANSFORM cmstransform; + DWORD i; + + TRACE( "( %p, 0x%08lx, %p, 0x%08lx, 0x%08lx, 0x%08lx ) stub\n", + profiles, nprofiles, intents, nintents, flags, cmm ); + + if (!profiles || !intents) return NULL; + + cmsprofiles = HeapAlloc( GetProcessHeap(), 0, nprofiles * sizeof(cmsHPROFILE) ); + + if (cmsprofiles) + { + for (i = 0; i < nprofiles; i++) + cmsprofiles[i] = MSCMS_hprofile2cmsprofile( profiles[i] ); + } + + cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, TYPE_BGR_8, + TYPE_BGR_8, *intents, 0 ); + HeapFree( GetProcessHeap(), 0, cmsprofiles ); + ret = MSCMS_create_htransform_handle( cmstransform ); + +#endif /* HAVE_LCMS_H */ + return ret; +} + +BOOL WINAPI DeleteColorTransform( HTRANSFORM transform ) +{ + BOOL ret = FALSE; +#ifdef HAVE_LCMS_H + cmsHTRANSFORM cmstransform; + + TRACE( "( %p )\n", transform ); + + cmstransform = MSCMS_htransform2cmstransform( transform ); + cmsDeleteTransform( cmstransform ); + + MSCMS_destroy_htransform_handle( transform ); + ret = TRUE; + +#endif /* HAVE_LCMS_H */ + return ret; +} diff --git a/include/icm.h b/include/icm.h index 164953395b0..88f0eaa53d8 100644 --- a/include/icm.h +++ b/include/icm.h @@ -308,6 +308,11 @@ typedef struct _tagCOLORMATCHSETUPW } COLORMATCHSETUPW, *PCOLORMATCHSETUPW, *LPCOLORMATCHSETUPW; BOOL WINAPI CloseColorProfile(HPROFILE); +HTRANSFORM WINAPI CreateColorTransformA(LPLOGCOLORSPACEA,HPROFILE,HPROFILE,DWORD); +HTRANSFORM WINAPI CreateColorTransformW(LPLOGCOLORSPACEW,HPROFILE,HPROFILE,DWORD); +#define CreateColorTransform WINELIB_NAME_AW(CreateColorTransform) +HTRANSFORM WINAPI CreateMultiProfileTransform(PHPROFILE,DWORD,PDWORD,DWORD,DWORD,DWORD); +BOOL WINAPI DeleteColorTransform(HTRANSFORM); BOOL WINAPI GetColorDirectoryA(PCSTR,PSTR,PDWORD); BOOL WINAPI GetColorDirectoryW(PCWSTR,PWSTR,PDWORD); #define GetColorDirectory WINELIB_NAME_AW(GetColorDirectory) @@ -315,6 +320,7 @@ BOOL WINAPI GetColorProfileElement(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID,PBO BOOL WINAPI GetColorProfileElementTag(HPROFILE,DWORD,PTAGTYPE); BOOL WINAPI GetColorProfileFromHandle(HPROFILE,PBYTE,PDWORD); BOOL WINAPI GetColorProfileHeader(HPROFILE,PPROFILEHEADER); +HCOLORSPACE WINAPI GetColorSpace(HDC); BOOL WINAPI GetCountColorProfileElements(HPROFILE,PDWORD); BOOL WINAPI GetStandardColorSpaceProfileA(PCSTR,DWORD,PSTR,PDWORD); BOOL WINAPI GetStandardColorSpaceProfileW(PCWSTR,DWORD,PWSTR,PDWORD); @@ -329,6 +335,7 @@ HPROFILE WINAPI OpenColorProfileW(PPROFILE,DWORD,DWORD,DWORD); #define OpenColorProfile WINELIB_NAME_AW(OpenColorProfile) BOOL WINAPI SetColorProfileElement(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID); BOOL WINAPI SetColorProfileHeader(HPROFILE,PPROFILEHEADER); +HCOLORSPACE WINAPI SetColorSpace(HDC,HCOLORSPACE); BOOL WINAPI SetStandardColorSpaceProfileA(PCSTR,DWORD,PSTR); BOOL WINAPI SetStandardColorSpaceProfileW(PCWSTR,DWORD,PWSTR); #define SetStandardColorSpaceProfile WINELIB_NAME_AW(SetStandardColorSpaceProfile)