Commit 3e30e298 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

mscms: Rewrite handle management to be thread-safe. Allocate handles dynamically.

parent 46489aed
...@@ -32,6 +32,8 @@ ...@@ -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 ) ...@@ -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 @@ ...@@ -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 );
struct profile
extern HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile, {
cmsHPROFILE cmsprofile, DWORD access ); HANDLE file;
extern void MSCMS_destroy_hprofile_handle( HPROFILE profile ); DWORD access;
icProfile *iccprofile;
extern cmsHTRANSFORM MSCMS_htransform2cmstransform( HTRANSFORM transform ); cmsHPROFILE cmsprofile;
extern HTRANSFORM MSCMS_create_htransform_handle( cmsHTRANSFORM cmstransform ); };
extern void MSCMS_destroy_htransform_handle( HTRANSFORM transform );
struct 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 );
......
...@@ -135,15 +135,21 @@ HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest, ...@@ -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, ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ) ...@@ -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 ...@@ -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, ...@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment