mscms: Rewrite handle management to be thread-safe. Allocate handles dynamically.
This commit is contained in:
parent
46489aeda2
commit
3e30e29847
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* MSCMS - Color Management System for Wine
|
* MSCMS - Color Management System for Wine
|
||||||
*
|
*
|
||||||
* Copyright 2004, 2005 Hans Leidekker
|
* Copyright 2004, 2005, 2008 Hans Leidekker
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -19,6 +19,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "wine/debug.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
|
@ -41,247 +43,208 @@ static CRITICAL_SECTION_DEBUG MSCMS_handle_cs_debug =
|
||||||
};
|
};
|
||||||
static CRITICAL_SECTION MSCMS_handle_cs = { &MSCMS_handle_cs_debug, -1, 0, 0, 0, 0 };
|
static CRITICAL_SECTION MSCMS_handle_cs = { &MSCMS_handle_cs_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
/* A simple structure to tie together a pointer to an icc profile, an lcms
|
static struct profile *profiletable;
|
||||||
* color profile handle and a Windows file handle. Windows color profile
|
static struct transform *transformtable;
|
||||||
* handles are built from indexes into an array of these structures. If
|
|
||||||
* the profile is memory based the file handle field is set to
|
|
||||||
* INVALID_HANDLE_VALUE. The 'access' field records the access parameter
|
|
||||||
* supplied to an OpenColorProfile() call, i.e. PROFILE_READ or PROFILE_READWRITE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct profile
|
static unsigned int num_profile_handles;
|
||||||
|
static unsigned int num_transform_handles;
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(mscms);
|
||||||
|
|
||||||
|
void free_handle_tables( void )
|
||||||
{
|
{
|
||||||
HANDLE file;
|
HeapFree( GetProcessHeap(), 0, profiletable );
|
||||||
DWORD access;
|
profiletable = NULL;
|
||||||
icProfile *iccprofile;
|
num_profile_handles = 0;
|
||||||
cmsHPROFILE cmsprofile;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct transform
|
HeapFree( GetProcessHeap(), 0, transformtable );
|
||||||
|
transformtable = NULL;
|
||||||
|
num_transform_handles = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct profile *grab_profile( HPROFILE handle )
|
||||||
{
|
{
|
||||||
cmsHTRANSFORM cmstransform;
|
DWORD_PTR index;
|
||||||
};
|
|
||||||
|
|
||||||
#define CMSMAXHANDLES 0x80
|
|
||||||
|
|
||||||
static struct profile profiletable[CMSMAXHANDLES];
|
|
||||||
static struct transform transformtable[CMSMAXHANDLES];
|
|
||||||
|
|
||||||
HPROFILE MSCMS_handle2hprofile( HANDLE file )
|
|
||||||
{
|
|
||||||
HPROFILE profile = NULL;
|
|
||||||
DWORD_PTR i;
|
|
||||||
|
|
||||||
if (!file) return NULL;
|
|
||||||
|
|
||||||
EnterCriticalSection( &MSCMS_handle_cs );
|
EnterCriticalSection( &MSCMS_handle_cs );
|
||||||
|
|
||||||
for (i = 0; i <= CMSMAXHANDLES; i++)
|
index = (DWORD_PTR)handle - 1;
|
||||||
|
if (index > num_profile_handles)
|
||||||
{
|
{
|
||||||
if (profiletable[i].file == file)
|
|
||||||
{
|
|
||||||
profile = (HPROFILE)(i + 1); goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE MSCMS_hprofile2handle( HPROFILE profile )
|
|
||||||
{
|
|
||||||
HANDLE file;
|
|
||||||
DWORD_PTR i;
|
|
||||||
|
|
||||||
EnterCriticalSection( &MSCMS_handle_cs );
|
|
||||||
|
|
||||||
i = (DWORD_PTR)profile - 1;
|
|
||||||
file = profiletable[i].file;
|
|
||||||
|
|
||||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD MSCMS_hprofile2access( HPROFILE profile )
|
|
||||||
{
|
|
||||||
DWORD access;
|
|
||||||
DWORD_PTR i;
|
|
||||||
|
|
||||||
EnterCriticalSection( &MSCMS_handle_cs );
|
|
||||||
|
|
||||||
i = (DWORD_PTR)profile - 1;
|
|
||||||
access = profiletable[i].access;
|
|
||||||
|
|
||||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
|
||||||
return access;
|
|
||||||
}
|
|
||||||
|
|
||||||
HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile )
|
|
||||||
{
|
|
||||||
HPROFILE profile = NULL;
|
|
||||||
DWORD_PTR i;
|
|
||||||
|
|
||||||
if (!cmsprofile) return NULL;
|
|
||||||
|
|
||||||
EnterCriticalSection( &MSCMS_handle_cs );
|
|
||||||
|
|
||||||
for (i = 0; i <= CMSMAXHANDLES; i++)
|
|
||||||
{
|
|
||||||
if (profiletable[i].cmsprofile == cmsprofile)
|
|
||||||
{
|
|
||||||
profile = (HPROFILE)(i + 1); goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmsHPROFILE MSCMS_hprofile2cmsprofile( HPROFILE profile )
|
|
||||||
{
|
|
||||||
cmsHPROFILE cmsprofile;
|
|
||||||
DWORD_PTR i;
|
|
||||||
|
|
||||||
EnterCriticalSection( &MSCMS_handle_cs );
|
|
||||||
|
|
||||||
i = (DWORD_PTR)profile - 1;
|
|
||||||
cmsprofile = profiletable[i].cmsprofile;
|
|
||||||
|
|
||||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
|
||||||
return cmsprofile;
|
|
||||||
}
|
|
||||||
|
|
||||||
HPROFILE MSCMS_iccprofile2hprofile( const icProfile *iccprofile )
|
|
||||||
{
|
|
||||||
HPROFILE profile = NULL;
|
|
||||||
DWORD_PTR i;
|
|
||||||
|
|
||||||
if (!iccprofile) return NULL;
|
|
||||||
|
|
||||||
EnterCriticalSection( &MSCMS_handle_cs );
|
|
||||||
|
|
||||||
for (i = 0; i <= CMSMAXHANDLES; i++)
|
|
||||||
{
|
|
||||||
if (profiletable[i].iccprofile == iccprofile)
|
|
||||||
{
|
|
||||||
profile = (HPROFILE)(i + 1); goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
icProfile *MSCMS_hprofile2iccprofile( HPROFILE profile )
|
|
||||||
{
|
|
||||||
icProfile *iccprofile;
|
|
||||||
DWORD_PTR i;
|
|
||||||
|
|
||||||
EnterCriticalSection( &MSCMS_handle_cs );
|
|
||||||
|
|
||||||
i = (DWORD_PTR)profile - 1;
|
|
||||||
iccprofile = profiletable[i].iccprofile;
|
|
||||||
|
|
||||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
|
||||||
return iccprofile;
|
|
||||||
}
|
|
||||||
|
|
||||||
HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile,
|
|
||||||
cmsHPROFILE cmsprofile, DWORD access )
|
|
||||||
{
|
|
||||||
HPROFILE profile = NULL;
|
|
||||||
DWORD_PTR i;
|
|
||||||
|
|
||||||
if (!cmsprofile || !iccprofile) return NULL;
|
|
||||||
|
|
||||||
EnterCriticalSection( &MSCMS_handle_cs );
|
|
||||||
|
|
||||||
for (i = 0; i <= CMSMAXHANDLES; i++)
|
|
||||||
{
|
|
||||||
if (profiletable[i].iccprofile == 0)
|
|
||||||
{
|
|
||||||
profiletable[i].file = file;
|
|
||||||
profiletable[i].access = access;
|
|
||||||
profiletable[i].iccprofile = iccprofile;
|
|
||||||
profiletable[i].cmsprofile = cmsprofile;
|
|
||||||
|
|
||||||
profile = (HPROFILE)(i + 1); goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MSCMS_destroy_hprofile_handle( HPROFILE profile )
|
|
||||||
{
|
|
||||||
DWORD_PTR i;
|
|
||||||
|
|
||||||
if (profile)
|
|
||||||
{
|
|
||||||
EnterCriticalSection( &MSCMS_handle_cs );
|
|
||||||
|
|
||||||
i = (DWORD_PTR)profile - 1;
|
|
||||||
memset( &profiletable[i], 0, sizeof(struct profile) );
|
|
||||||
|
|
||||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
return &profiletable[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsHTRANSFORM MSCMS_htransform2cmstransform( HTRANSFORM transform )
|
void release_profile( struct profile *profile )
|
||||||
{
|
{
|
||||||
cmsHTRANSFORM cmstransform;
|
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||||
DWORD_PTR i;
|
}
|
||||||
|
|
||||||
|
struct transform *grab_transform( HTRANSFORM handle )
|
||||||
|
{
|
||||||
|
DWORD_PTR index;
|
||||||
|
|
||||||
EnterCriticalSection( &MSCMS_handle_cs );
|
EnterCriticalSection( &MSCMS_handle_cs );
|
||||||
|
|
||||||
i = (DWORD_PTR)transform - 1;
|
index = (DWORD_PTR)handle - 1;
|
||||||
cmstransform = transformtable[i].cmstransform;
|
if (index > num_transform_handles)
|
||||||
|
|
||||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
|
||||||
return cmstransform;
|
|
||||||
}
|
|
||||||
|
|
||||||
HTRANSFORM MSCMS_create_htransform_handle( cmsHTRANSFORM cmstransform )
|
|
||||||
{
|
|
||||||
HTRANSFORM transform = NULL;
|
|
||||||
DWORD_PTR 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 )
|
|
||||||
{
|
|
||||||
DWORD_PTR i;
|
|
||||||
|
|
||||||
if (transform)
|
|
||||||
{
|
|
||||||
EnterCriticalSection( &MSCMS_handle_cs );
|
|
||||||
|
|
||||||
i = (DWORD_PTR)transform - 1;
|
|
||||||
memset( &transformtable[i], 0, sizeof(struct transform) );
|
|
||||||
|
|
||||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
return &transformtable[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void release_transform( struct transform *transform )
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||||
|
}
|
||||||
|
|
||||||
|
static HPROFILE alloc_profile_handle( void )
|
||||||
|
{
|
||||||
|
DWORD_PTR index;
|
||||||
|
struct profile *p;
|
||||||
|
unsigned int count = 128;
|
||||||
|
|
||||||
|
for (index = 0; index < num_profile_handles; index++)
|
||||||
|
{
|
||||||
|
if (!profiletable[index].iccprofile) return (HPROFILE)(index + 1);
|
||||||
|
}
|
||||||
|
if (!profiletable)
|
||||||
|
{
|
||||||
|
p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(struct profile) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count = num_profile_handles * 2;
|
||||||
|
p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, profiletable, count * sizeof(struct profile) );
|
||||||
|
}
|
||||||
|
if (!p) return NULL;
|
||||||
|
|
||||||
|
profiletable = p;
|
||||||
|
num_profile_handles = count;
|
||||||
|
|
||||||
|
return (HPROFILE)(index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
HPROFILE create_profile( struct profile *profile )
|
||||||
|
{
|
||||||
|
HPROFILE handle;
|
||||||
|
|
||||||
|
EnterCriticalSection( &MSCMS_handle_cs );
|
||||||
|
|
||||||
|
if ((handle = alloc_profile_handle()))
|
||||||
|
{
|
||||||
|
DWORD_PTR index = (DWORD_PTR)handle - 1;
|
||||||
|
memcpy( &profiletable[index], profile, sizeof(struct profile) );
|
||||||
|
}
|
||||||
|
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL close_profile( HPROFILE handle )
|
||||||
|
{
|
||||||
|
DWORD_PTR index;
|
||||||
|
struct profile *profile;
|
||||||
|
|
||||||
|
EnterCriticalSection( &MSCMS_handle_cs );
|
||||||
|
|
||||||
|
index = (DWORD_PTR)handle - 1;
|
||||||
|
if (index > num_profile_handles)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
profile = &profiletable[index];
|
||||||
|
|
||||||
|
if (profile->file != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
if (profile->access & PROFILE_READWRITE)
|
||||||
|
{
|
||||||
|
DWORD written, size = MSCMS_get_profile_size( profile->iccprofile );
|
||||||
|
|
||||||
|
if (SetFilePointer( profile->file, 0, NULL, FILE_BEGIN ) ||
|
||||||
|
!WriteFile( profile->file, profile->iccprofile, size, &written, NULL ) ||
|
||||||
|
written != size)
|
||||||
|
{
|
||||||
|
ERR( "Unable to write color profile\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseHandle( profile->file );
|
||||||
|
}
|
||||||
|
cmsCloseProfile( profile->cmsprofile );
|
||||||
|
HeapFree( GetProcessHeap(), 0, profile->iccprofile );
|
||||||
|
|
||||||
|
memset( profile, 0, sizeof(struct profile) );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HTRANSFORM alloc_transform_handle( void )
|
||||||
|
{
|
||||||
|
DWORD_PTR index;
|
||||||
|
struct transform *p;
|
||||||
|
unsigned int count = 128;
|
||||||
|
|
||||||
|
for (index = 0; index < num_transform_handles; index++)
|
||||||
|
{
|
||||||
|
if (!transformtable[index].cmstransform) return (HTRANSFORM)(index + 1);
|
||||||
|
}
|
||||||
|
if (!transformtable)
|
||||||
|
{
|
||||||
|
p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(struct transform) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count = num_transform_handles * 2;
|
||||||
|
p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, transformtable, count * sizeof(struct transform) );
|
||||||
|
}
|
||||||
|
if (!p) return NULL;
|
||||||
|
|
||||||
|
transformtable = p;
|
||||||
|
num_transform_handles = count;
|
||||||
|
|
||||||
|
return (HTRANSFORM)(index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
HTRANSFORM create_transform( struct transform *transform )
|
||||||
|
{
|
||||||
|
HTRANSFORM handle;
|
||||||
|
|
||||||
|
EnterCriticalSection( &MSCMS_handle_cs );
|
||||||
|
|
||||||
|
if ((handle = alloc_transform_handle()))
|
||||||
|
{
|
||||||
|
DWORD_PTR index = (DWORD_PTR)handle - 1;
|
||||||
|
memcpy( &transformtable[index], transform, sizeof(struct transform) );
|
||||||
|
}
|
||||||
|
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL close_transform( HTRANSFORM handle )
|
||||||
|
{
|
||||||
|
DWORD_PTR index;
|
||||||
|
struct transform *transform;
|
||||||
|
|
||||||
|
EnterCriticalSection( &MSCMS_handle_cs );
|
||||||
|
|
||||||
|
index = (DWORD_PTR)handle - 1;
|
||||||
|
if (index > num_transform_handles)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
transform = &transformtable[index];
|
||||||
|
|
||||||
|
cmsDeleteTransform( transform->cmstransform );
|
||||||
|
memset( transform, 0, sizeof(struct transform) );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
#include "icm.h"
|
#include "icm.h"
|
||||||
|
|
||||||
|
#include "mscms_priv.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(mscms);
|
WINE_DEFAULT_DEBUG_CHANNEL(mscms);
|
||||||
|
|
||||||
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
|
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
|
||||||
|
@ -44,6 +46,7 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
|
||||||
DisableThreadLibraryCalls( hinst );
|
DisableThreadLibraryCalls( hinst );
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
|
free_handle_tables();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -66,21 +66,39 @@
|
||||||
#define DWORD DWORD
|
#define DWORD DWORD
|
||||||
#define LPDWORD LPDWORD
|
#define LPDWORD LPDWORD
|
||||||
|
|
||||||
extern DWORD MSCMS_hprofile2access( HPROFILE );
|
/* A simple structure to tie together a pointer to an icc profile, an lcms
|
||||||
extern HPROFILE MSCMS_handle2hprofile( HANDLE file );
|
* color profile handle and a Windows file handle. If the profile is memory
|
||||||
extern HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile );
|
* based the file handle field is set to INVALID_HANDLE_VALUE. The 'access'
|
||||||
extern HPROFILE MSCMS_iccprofile2hprofile( const icProfile *iccprofile );
|
* field records the access parameter supplied to an OpenColorProfile()
|
||||||
extern HANDLE MSCMS_hprofile2handle( HPROFILE profile );
|
* call, i.e. PROFILE_READ or PROFILE_READWRITE.
|
||||||
extern cmsHPROFILE MSCMS_hprofile2cmsprofile( HPROFILE profile );
|
*/
|
||||||
extern icProfile *MSCMS_hprofile2iccprofile( HPROFILE profile );
|
|
||||||
|
|
||||||
extern HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile,
|
struct profile
|
||||||
cmsHPROFILE cmsprofile, DWORD access );
|
{
|
||||||
extern void MSCMS_destroy_hprofile_handle( HPROFILE profile );
|
HANDLE file;
|
||||||
|
DWORD access;
|
||||||
|
icProfile *iccprofile;
|
||||||
|
cmsHPROFILE cmsprofile;
|
||||||
|
};
|
||||||
|
|
||||||
extern cmsHTRANSFORM MSCMS_htransform2cmstransform( HTRANSFORM transform );
|
struct transform
|
||||||
extern HTRANSFORM MSCMS_create_htransform_handle( cmsHTRANSFORM cmstransform );
|
{
|
||||||
extern void MSCMS_destroy_htransform_handle( HTRANSFORM transform );
|
cmsHTRANSFORM cmstransform;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern HPROFILE create_profile( struct profile * );
|
||||||
|
extern BOOL close_profile( HPROFILE );
|
||||||
|
|
||||||
|
extern HTRANSFORM create_transform( struct transform * );
|
||||||
|
extern BOOL close_transform( HTRANSFORM );
|
||||||
|
|
||||||
|
struct profile *grab_profile( HPROFILE );
|
||||||
|
struct transform *grab_transform( HTRANSFORM );
|
||||||
|
|
||||||
|
void release_profile( struct profile * );
|
||||||
|
void release_transform( struct transform * );
|
||||||
|
|
||||||
|
extern void free_handle_tables( void );
|
||||||
|
|
||||||
extern DWORD MSCMS_get_tag_count( const icProfile *iccprofile );
|
extern DWORD MSCMS_get_tag_count( const icProfile *iccprofile );
|
||||||
extern void MSCMS_get_tag_by_index( icProfile *iccprofile, DWORD index, icTag *tag );
|
extern void MSCMS_get_tag_by_index( icProfile *iccprofile, DWORD index, icTag *tag );
|
||||||
|
|
|
@ -333,38 +333,46 @@ BOOL WINAPI GetColorDirectoryW( PCWSTR machine, PWSTR buffer, PDWORD size )
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI GetColorProfileElement( HPROFILE profile, TAGTYPE type, DWORD offset, PDWORD size,
|
BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size,
|
||||||
PVOID buffer, PBOOL ref )
|
PVOID buffer, PBOOL ref )
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
struct profile *profile = grab_profile( handle );
|
||||||
DWORD i, count;
|
DWORD i, count;
|
||||||
icTag tag;
|
icTag tag;
|
||||||
|
|
||||||
TRACE( "( %p, 0x%08x, %d, %p, %p, %p )\n", profile, type, offset, size, buffer, ref );
|
TRACE( "( %p, 0x%08x, %d, %p, %p, %p )\n", handle, type, offset, size, buffer, ref );
|
||||||
|
|
||||||
if (!iccprofile || !size || !ref) return FALSE;
|
if (!profile) return FALSE;
|
||||||
count = MSCMS_get_tag_count( iccprofile );
|
|
||||||
|
if (!size || !ref)
|
||||||
|
{
|
||||||
|
release_profile( profile );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
count = MSCMS_get_tag_count( profile->iccprofile );
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
MSCMS_get_tag_by_index( iccprofile, i, &tag );
|
MSCMS_get_tag_by_index( profile->iccprofile, i, &tag );
|
||||||
|
|
||||||
if (tag.sig == type)
|
if (tag.sig == type)
|
||||||
{
|
{
|
||||||
if ((tag.size - offset) > *size || !buffer)
|
if ((tag.size - offset) > *size || !buffer)
|
||||||
{
|
{
|
||||||
*size = (tag.size - offset);
|
*size = (tag.size - offset);
|
||||||
|
release_profile( profile );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
MSCMS_get_tag_data( profile->iccprofile, &tag, offset, buffer );
|
||||||
MSCMS_get_tag_data( iccprofile, &tag, offset, buffer );
|
|
||||||
|
|
||||||
*ref = FALSE; /* FIXME: calculate properly */
|
*ref = FALSE; /* FIXME: calculate properly */
|
||||||
|
release_profile( profile );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_profile( profile );
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -388,24 +396,33 @@ BOOL WINAPI GetColorProfileElement( HPROFILE profile, TAGTYPE type, DWORD offset
|
||||||
* The tag table index starts at 1.
|
* The tag table index starts at 1.
|
||||||
* Use GetCountColorProfileElements to retrieve a count of tagged elements.
|
* Use GetCountColorProfileElements to retrieve a count of tagged elements.
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI GetColorProfileElementTag( HPROFILE profile, DWORD index, PTAGTYPE type )
|
BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE type )
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
struct profile *profile = grab_profile( handle );
|
||||||
DWORD count;
|
DWORD count;
|
||||||
icTag tag;
|
icTag tag;
|
||||||
|
|
||||||
TRACE( "( %p, %d, %p )\n", profile, index, type );
|
TRACE( "( %p, %d, %p )\n", handle, index, type );
|
||||||
|
|
||||||
if (!iccprofile || !type) return FALSE;
|
if (!profile) return FALSE;
|
||||||
|
|
||||||
count = MSCMS_get_tag_count( iccprofile );
|
if (!type)
|
||||||
if (index > count || index < 1) return FALSE;
|
{
|
||||||
|
release_profile( profile );
|
||||||
MSCMS_get_tag_by_index( iccprofile, index - 1, &tag );
|
return FALSE;
|
||||||
|
}
|
||||||
|
count = MSCMS_get_tag_count( profile->iccprofile );
|
||||||
|
if (index > count || index < 1)
|
||||||
|
{
|
||||||
|
release_profile( profile );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
MSCMS_get_tag_by_index( profile->iccprofile, index - 1, &tag );
|
||||||
*type = tag.sig;
|
*type = tag.sig;
|
||||||
|
|
||||||
|
release_profile( profile );
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
|
@ -430,28 +447,36 @@ BOOL WINAPI GetColorProfileElementTag( HPROFILE profile, DWORD index, PTAGTYPE t
|
||||||
* NOTES
|
* NOTES
|
||||||
* The profile returned will be in big-endian format.
|
* The profile returned will be in big-endian format.
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI GetColorProfileFromHandle( HPROFILE profile, PBYTE buffer, PDWORD size )
|
BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD size )
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
struct profile *profile = grab_profile( handle );
|
||||||
PROFILEHEADER header;
|
PROFILEHEADER header;
|
||||||
|
|
||||||
TRACE( "( %p, %p, %p )\n", profile, buffer, size );
|
TRACE( "( %p, %p, %p )\n", handle, buffer, size );
|
||||||
|
|
||||||
if (!iccprofile || !size) return FALSE;
|
if (!profile) return FALSE;
|
||||||
MSCMS_get_profile_header( iccprofile, &header );
|
|
||||||
|
if (!size)
|
||||||
|
{
|
||||||
|
release_profile( profile );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
MSCMS_get_profile_header( profile->iccprofile, &header );
|
||||||
|
|
||||||
if (!buffer || header.phSize > *size)
|
if (!buffer || header.phSize > *size)
|
||||||
{
|
{
|
||||||
*size = header.phSize;
|
*size = header.phSize;
|
||||||
|
release_profile( profile );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No endian conversion needed */
|
/* No endian conversion needed */
|
||||||
memcpy( buffer, iccprofile, header.phSize );
|
memcpy( buffer, profile->iccprofile, header.phSize );
|
||||||
|
|
||||||
*size = header.phSize;
|
*size = header.phSize;
|
||||||
|
|
||||||
|
release_profile( profile );
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
|
@ -474,16 +499,23 @@ BOOL WINAPI GetColorProfileFromHandle( HPROFILE profile, PBYTE buffer, PDWORD si
|
||||||
* NOTES
|
* NOTES
|
||||||
* The profile header returned will be adjusted for endianess.
|
* The profile header returned will be adjusted for endianess.
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI GetColorProfileHeader( HPROFILE profile, PPROFILEHEADER header )
|
BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
struct profile *profile = grab_profile( handle );
|
||||||
|
|
||||||
TRACE( "( %p, %p )\n", profile, header );
|
TRACE( "( %p, %p )\n", handle, header );
|
||||||
|
|
||||||
if (!iccprofile || !header) return FALSE;
|
if (!profile) return FALSE;
|
||||||
|
|
||||||
MSCMS_get_profile_header( iccprofile, header );
|
if (!header)
|
||||||
|
{
|
||||||
|
release_profile( profile );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
MSCMS_get_profile_header( profile->iccprofile, header );
|
||||||
|
|
||||||
|
release_profile( profile );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -505,16 +537,24 @@ BOOL WINAPI GetColorProfileHeader( HPROFILE profile, PPROFILEHEADER header )
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI GetCountColorProfileElements( HPROFILE profile, PDWORD count )
|
BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count )
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
struct profile *profile = grab_profile( handle );
|
||||||
|
|
||||||
TRACE( "( %p, %p )\n", profile, count );
|
TRACE( "( %p, %p )\n", handle, count );
|
||||||
|
|
||||||
if (!iccprofile || !count) return FALSE;
|
if (!profile) return FALSE;
|
||||||
*count = MSCMS_get_tag_count( iccprofile );
|
|
||||||
|
if (!count)
|
||||||
|
{
|
||||||
|
release_profile( profile );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
*count = MSCMS_get_tag_count( profile->iccprofile );
|
||||||
|
|
||||||
|
release_profile( profile );
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
|
@ -1113,23 +1153,28 @@ BOOL WINAPI InstallColorProfileW( PCWSTR machine, PCWSTR profile )
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI IsColorProfileTagPresent( HPROFILE profile, TAGTYPE type, PBOOL present )
|
BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL present )
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
struct profile *profile = grab_profile( handle );
|
||||||
DWORD i, count;
|
DWORD i, count;
|
||||||
icTag tag;
|
icTag tag;
|
||||||
|
|
||||||
TRACE( "( %p, 0x%08x, %p )\n", profile, type, present );
|
TRACE( "( %p, 0x%08x, %p )\n", handle, type, present );
|
||||||
|
|
||||||
if (!iccprofile || !present) return FALSE;
|
if (!profile) return FALSE;
|
||||||
|
|
||||||
count = MSCMS_get_tag_count( iccprofile );
|
if (!present)
|
||||||
|
{
|
||||||
|
release_profile( profile );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
count = MSCMS_get_tag_count( profile->iccprofile );
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
MSCMS_get_tag_by_index( iccprofile, i, &tag );
|
MSCMS_get_tag_by_index( profile->iccprofile, i, &tag );
|
||||||
|
|
||||||
if (tag.sig == type)
|
if (tag.sig == type)
|
||||||
{
|
{
|
||||||
|
@ -1137,6 +1182,7 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE profile, TAGTYPE type, PBOOL pres
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_profile( profile );
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1156,16 +1202,23 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE profile, TAGTYPE type, PBOOL pres
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI IsColorProfileValid( HPROFILE profile, PBOOL valid )
|
BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid )
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
struct profile *profile = grab_profile( handle );
|
||||||
|
|
||||||
TRACE( "( %p, %p )\n", profile, valid );
|
TRACE( "( %p, %p )\n", handle, valid );
|
||||||
|
|
||||||
if (!valid) return FALSE;
|
if (!profile) return FALSE;
|
||||||
if (iccprofile) return *valid = TRUE;
|
|
||||||
|
if (!valid)
|
||||||
|
{
|
||||||
|
release_profile( profile );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (profile->iccprofile) ret = *valid = TRUE;
|
||||||
|
release_profile( profile );
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1188,34 +1241,44 @@ BOOL WINAPI IsColorProfileValid( HPROFILE profile, PBOOL valid )
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI SetColorProfileElement( HPROFILE profile, TAGTYPE type, DWORD offset, PDWORD size,
|
BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size,
|
||||||
PVOID buffer )
|
PVOID buffer )
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
struct profile *profile = grab_profile( handle );
|
||||||
DWORD i, count, access = MSCMS_hprofile2access( profile );
|
DWORD i, count;
|
||||||
icTag tag;
|
icTag tag;
|
||||||
|
|
||||||
TRACE( "( %p, 0x%08x, %d, %p, %p )\n", profile, type, offset, size, buffer );
|
TRACE( "( %p, 0x%08x, %d, %p, %p )\n", handle, type, offset, size, buffer );
|
||||||
|
|
||||||
if (!iccprofile || !size || !buffer) return FALSE;
|
if (!profile) return FALSE;
|
||||||
if (!(access & PROFILE_READWRITE)) return FALSE;
|
|
||||||
|
|
||||||
count = MSCMS_get_tag_count( iccprofile );
|
if (!size || !buffer || !(profile->access & PROFILE_READWRITE))
|
||||||
|
{
|
||||||
|
release_profile( profile );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
count = MSCMS_get_tag_count( profile->iccprofile );
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
MSCMS_get_tag_by_index( iccprofile, i, &tag );
|
MSCMS_get_tag_by_index( profile->iccprofile, i, &tag );
|
||||||
|
|
||||||
if (tag.sig == type)
|
if (tag.sig == type)
|
||||||
{
|
{
|
||||||
if (offset > tag.size) return FALSE;
|
if (offset > tag.size)
|
||||||
|
{
|
||||||
|
release_profile( profile );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
MSCMS_set_tag_data( profile->iccprofile, &tag, offset, buffer );
|
||||||
|
|
||||||
MSCMS_set_tag_data( iccprofile, &tag, offset, buffer );
|
release_profile( profile );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_profile( profile );
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1234,18 +1297,23 @@ BOOL WINAPI SetColorProfileElement( HPROFILE profile, TAGTYPE type, DWORD offset
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI SetColorProfileHeader( HPROFILE profile, PPROFILEHEADER header )
|
BOOL WINAPI SetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
struct profile *profile = grab_profile( handle );
|
||||||
DWORD access = MSCMS_hprofile2access( profile );
|
|
||||||
|
|
||||||
TRACE( "( %p, %p )\n", profile, header );
|
TRACE( "( %p, %p )\n", handle, header );
|
||||||
|
|
||||||
if (!iccprofile || !header) return FALSE;
|
if (!profile) return FALSE;
|
||||||
if (!(access & PROFILE_READWRITE)) return FALSE;
|
|
||||||
|
|
||||||
MSCMS_set_profile_header( iccprofile, header );
|
if (!header || !(profile->access & PROFILE_READWRITE))
|
||||||
|
{
|
||||||
|
release_profile( profile );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
MSCMS_set_profile_header( profile->iccprofile, header );
|
||||||
|
|
||||||
|
release_profile( profile );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -1441,7 +1509,16 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmsprofile)
|
if (cmsprofile)
|
||||||
return MSCMS_create_hprofile_handle( handle, iccprofile, cmsprofile, access );
|
{
|
||||||
|
struct profile profile;
|
||||||
|
|
||||||
|
profile.file = handle;
|
||||||
|
profile.access = access;
|
||||||
|
profile.iccprofile = iccprofile;
|
||||||
|
profile.cmsprofile = cmsprofile;
|
||||||
|
|
||||||
|
return create_profile( &profile );
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1463,30 +1540,9 @@ BOOL WINAPI CloseColorProfile( HPROFILE profile )
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
|
||||||
HANDLE file = MSCMS_hprofile2handle( profile );
|
|
||||||
DWORD access = MSCMS_hprofile2access( profile );
|
|
||||||
|
|
||||||
TRACE( "( %p )\n", profile );
|
TRACE( "( %p )\n", profile );
|
||||||
|
ret = close_profile( profile );
|
||||||
if (file != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
if (access & PROFILE_READWRITE)
|
|
||||||
{
|
|
||||||
DWORD written, size = MSCMS_get_profile_size( iccprofile );
|
|
||||||
|
|
||||||
if (SetFilePointer( file, 0, NULL, FILE_BEGIN ) ||
|
|
||||||
!WriteFile( file, iccprofile, size, &written, NULL ) || written != size)
|
|
||||||
{
|
|
||||||
ERR( "Unable to write color profile\n" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CloseHandle( file );
|
|
||||||
}
|
|
||||||
ret = cmsCloseProfile( MSCMS_hprofile2cmsprofile( profile ) );
|
|
||||||
HeapFree( GetProcessHeap(), 0, iccprofile );
|
|
||||||
|
|
||||||
MSCMS_destroy_hprofile_handle( profile );
|
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -135,15 +135,21 @@ HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest,
|
||||||
{
|
{
|
||||||
HTRANSFORM ret = NULL;
|
HTRANSFORM ret = NULL;
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
cmsHTRANSFORM cmstransform;
|
struct transform transform;
|
||||||
|
struct profile *dst, *tgt = NULL;
|
||||||
cmsHPROFILE cmsinput, cmsoutput, cmstarget = NULL;
|
cmsHPROFILE cmsinput, cmsoutput, cmstarget = NULL;
|
||||||
DWORD in_format, out_format, proofing = 0;
|
DWORD in_format, out_format, proofing = 0;
|
||||||
int intent;
|
int intent;
|
||||||
|
|
||||||
TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags );
|
TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags );
|
||||||
|
|
||||||
if (!space || !dest) return FALSE;
|
if (!space || !(dst = grab_profile( dest ))) return FALSE;
|
||||||
|
|
||||||
|
if (target && !(tgt = grab_profile( target )))
|
||||||
|
{
|
||||||
|
release_profile( dst );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
intent = space->lcsIntent > 3 ? INTENT_PERCEPTUAL : space->lcsIntent;
|
intent = space->lcsIntent > 3 ? INTENT_PERCEPTUAL : space->lcsIntent;
|
||||||
|
|
||||||
TRACE( "lcsIntent: %x\n", space->lcsIntent );
|
TRACE( "lcsIntent: %x\n", space->lcsIntent );
|
||||||
|
@ -157,13 +163,16 @@ HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest,
|
||||||
if (target)
|
if (target)
|
||||||
{
|
{
|
||||||
proofing = cmsFLAGS_SOFTPROOFING;
|
proofing = cmsFLAGS_SOFTPROOFING;
|
||||||
cmstarget = MSCMS_hprofile2cmsprofile( target );
|
cmstarget = tgt->cmsprofile;
|
||||||
}
|
}
|
||||||
cmsoutput = MSCMS_hprofile2cmsprofile( dest );
|
cmsoutput = dst->cmsprofile;
|
||||||
cmstransform = cmsCreateProofingTransform(cmsinput, in_format, cmsoutput, out_format, cmstarget,
|
transform.cmstransform = cmsCreateProofingTransform(cmsinput, in_format, cmsoutput, out_format, cmstarget,
|
||||||
intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing);
|
intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing);
|
||||||
|
|
||||||
ret = MSCMS_create_htransform_handle( cmstransform );
|
ret = create_transform( &transform );
|
||||||
|
|
||||||
|
if (tgt) release_profile( tgt );
|
||||||
|
release_profile( dst );
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -191,7 +200,8 @@ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofil
|
||||||
HTRANSFORM ret = NULL;
|
HTRANSFORM ret = NULL;
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
cmsHPROFILE *cmsprofiles, cmsconvert = NULL;
|
cmsHPROFILE *cmsprofiles, cmsconvert = NULL;
|
||||||
cmsHTRANSFORM cmstransform;
|
struct transform transform;
|
||||||
|
struct profile *profile0, *profile1;
|
||||||
DWORD in_format, out_format;
|
DWORD in_format, out_format;
|
||||||
|
|
||||||
TRACE( "( %p, 0x%08x, %p, 0x%08x, 0x%08x, 0x%08x )\n",
|
TRACE( "( %p, 0x%08x, %p, 0x%08x, 0x%08x, 0x%08x )\n",
|
||||||
|
@ -205,6 +215,14 @@ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofil
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
profile0 = grab_profile( profiles[0] );
|
||||||
|
if (!profile0) return NULL;
|
||||||
|
profile1 = grab_profile( profiles[1] );
|
||||||
|
if (!profile1)
|
||||||
|
{
|
||||||
|
release_profile( profile0 );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
in_format = from_profile( profiles[0] );
|
in_format = from_profile( profiles[0] );
|
||||||
out_format = from_profile( profiles[nprofiles - 1] );
|
out_format = from_profile( profiles[nprofiles - 1] );
|
||||||
|
|
||||||
|
@ -218,23 +236,26 @@ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofil
|
||||||
cmsprofiles = HeapAlloc( GetProcessHeap(), 0, (nprofiles + 1) * sizeof(cmsHPROFILE *) );
|
cmsprofiles = HeapAlloc( GetProcessHeap(), 0, (nprofiles + 1) * sizeof(cmsHPROFILE *) );
|
||||||
if (cmsprofiles)
|
if (cmsprofiles)
|
||||||
{
|
{
|
||||||
cmsprofiles[0] = MSCMS_hprofile2cmsprofile( profiles[0] );
|
cmsprofiles[0] = profile0->cmsprofile;
|
||||||
if (cmsconvert)
|
if (cmsconvert)
|
||||||
{
|
{
|
||||||
cmsprofiles[1] = cmsconvert;
|
cmsprofiles[1] = cmsconvert;
|
||||||
cmsprofiles[2] = MSCMS_hprofile2cmsprofile( profiles[1] );
|
cmsprofiles[2] = profile1->cmsprofile;
|
||||||
nprofiles++;
|
nprofiles++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cmsprofiles[1] = MSCMS_hprofile2cmsprofile( profiles[1] );
|
cmsprofiles[1] = profile1->cmsprofile;
|
||||||
}
|
}
|
||||||
cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, in_format, out_format, *intents, 0 );
|
transform.cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, in_format, out_format, *intents, 0 );
|
||||||
|
|
||||||
HeapFree( GetProcessHeap(), 0, cmsprofiles );
|
HeapFree( GetProcessHeap(), 0, cmsprofiles );
|
||||||
ret = MSCMS_create_htransform_handle( cmstransform );
|
ret = create_transform( &transform );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
release_profile( profile0 );
|
||||||
|
release_profile( profile1 );
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -251,19 +272,14 @@ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofil
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI DeleteColorTransform( HTRANSFORM transform )
|
BOOL WINAPI DeleteColorTransform( HTRANSFORM handle )
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
cmsHTRANSFORM cmstransform;
|
|
||||||
|
|
||||||
TRACE( "( %p )\n", transform );
|
TRACE( "( %p )\n", handle );
|
||||||
|
|
||||||
cmstransform = MSCMS_htransform2cmstransform( transform );
|
ret = close_transform( handle );
|
||||||
cmsDeleteTransform( cmstransform );
|
|
||||||
|
|
||||||
MSCMS_destroy_htransform_handle( transform );
|
|
||||||
ret = TRUE;
|
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -291,22 +307,23 @@ BOOL WINAPI DeleteColorTransform( HTRANSFORM transform )
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI TranslateBitmapBits( HTRANSFORM transform, PVOID srcbits, BMFORMAT input,
|
BOOL WINAPI TranslateBitmapBits( HTRANSFORM handle, PVOID srcbits, BMFORMAT input,
|
||||||
DWORD width, DWORD height, DWORD inputstride, PVOID destbits, BMFORMAT output,
|
DWORD width, DWORD height, DWORD inputstride, PVOID destbits, BMFORMAT output,
|
||||||
DWORD outputstride, PBMCALLBACKFN callback, ULONG data )
|
DWORD outputstride, PBMCALLBACKFN callback, ULONG data )
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
cmsHTRANSFORM cmstransform;
|
struct transform *transform = grab_transform( handle );
|
||||||
|
|
||||||
TRACE( "( %p, %p, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x )\n",
|
TRACE( "( %p, %p, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x )\n",
|
||||||
transform, srcbits, input, width, height, inputstride, destbits, output,
|
handle, srcbits, input, width, height, inputstride, destbits, output,
|
||||||
outputstride, callback, data );
|
outputstride, callback, data );
|
||||||
|
|
||||||
cmstransform = MSCMS_htransform2cmstransform( transform );
|
if (!transform) return FALSE;
|
||||||
cmsChangeBuffersFormat( cmstransform, from_bmformat(input), from_bmformat(output) );
|
cmsChangeBuffersFormat( transform->cmstransform, from_bmformat(input), from_bmformat(output) );
|
||||||
|
|
||||||
cmsDoTransform( cmstransform, srcbits, destbits, width * height );
|
cmsDoTransform( transform->cmstransform, srcbits, destbits, width * height );
|
||||||
|
release_transform( transform );
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
|
@ -330,16 +347,20 @@ BOOL WINAPI TranslateBitmapBits( HTRANSFORM transform, PVOID srcbits, BMFORMAT i
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI TranslateColors( HTRANSFORM transform, PCOLOR in, DWORD count,
|
BOOL WINAPI TranslateColors( HTRANSFORM handle, PCOLOR in, DWORD count,
|
||||||
COLORTYPE input_type, PCOLOR out, COLORTYPE output_type )
|
COLORTYPE input_type, PCOLOR out, COLORTYPE output_type )
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
#ifdef HAVE_LCMS
|
#ifdef HAVE_LCMS
|
||||||
cmsHTRANSFORM xfrm = MSCMS_htransform2cmstransform( transform );
|
struct transform *transform = grab_transform( handle );
|
||||||
|
cmsHTRANSFORM xfrm;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
TRACE( "( %p, %p, %d, %d, %p, %d )\n", transform, in, count, input_type, out, output_type );
|
TRACE( "( %p, %p, %d, %d, %p, %d )\n", handle, in, count, input_type, out, output_type );
|
||||||
|
|
||||||
|
if (!transform) return FALSE;
|
||||||
|
|
||||||
|
xfrm = transform->cmstransform;
|
||||||
cmsChangeBuffersFormat( xfrm, from_type(input_type), from_type(output_type) );
|
cmsChangeBuffersFormat( xfrm, from_type(input_type), from_type(output_type) );
|
||||||
|
|
||||||
switch (input_type)
|
switch (input_type)
|
||||||
|
@ -418,6 +439,7 @@ BOOL WINAPI TranslateColors( HTRANSFORM transform, PCOLOR in, DWORD count,
|
||||||
FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
|
FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
release_transform( transform );
|
||||||
|
|
||||||
#endif /* HAVE_LCMS */
|
#endif /* HAVE_LCMS */
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue