diff --git a/dlls/mscms/handle.c b/dlls/mscms/handle.c index 5b862ddeacd..63c6a011bb3 100644 --- a/dlls/mscms/handle.c +++ b/dlls/mscms/handle.c @@ -30,6 +30,8 @@ #include "mscms_priv.h" +WINE_DEFAULT_DEBUG_CHANNEL(mscms); + static CRITICAL_SECTION mscms_handle_cs; static CRITICAL_SECTION_DEBUG mscms_handle_cs_debug = { @@ -40,209 +42,107 @@ static CRITICAL_SECTION_DEBUG mscms_handle_cs_debug = }; static CRITICAL_SECTION mscms_handle_cs = { &mscms_handle_cs_debug, -1, 0, 0, 0, 0 }; -static struct profile *profiletable; -static cmsHTRANSFORM *transformtable; +static struct object **handle_table; +static ULONG_PTR next_handle; +static ULONG_PTR max_handles; -static unsigned int num_profile_handles; -static unsigned int num_transform_handles; - -WINE_DEFAULT_DEBUG_CHANNEL(mscms); - -void free_handle_tables( void ) +struct object *grab_object( HANDLE handle, enum object_type type ) { - free( profiletable ); - profiletable = NULL; - num_profile_handles = 0; - - free( transformtable ); - transformtable = NULL; - num_transform_handles = 0; - - DeleteCriticalSection( &mscms_handle_cs ); -} - -struct profile *grab_profile( HPROFILE handle ) -{ - DWORD_PTR index; + struct object *obj = NULL; + ULONG_PTR index = (ULONG_PTR)handle; EnterCriticalSection( &mscms_handle_cs ); - - index = (DWORD_PTR)handle - 1; - if (index > num_profile_handles) + if (index > 0 && index <= max_handles) { - LeaveCriticalSection( &mscms_handle_cs ); - return NULL; - } - return &profiletable[index]; -} - -void release_profile( struct profile *profile ) -{ - LeaveCriticalSection( &mscms_handle_cs ); -} - -cmsHTRANSFORM grab_transform( HTRANSFORM handle ) -{ - DWORD_PTR index; - - EnterCriticalSection( &mscms_handle_cs ); - - index = (DWORD_PTR)handle - 1; - if (index > num_transform_handles) - { - LeaveCriticalSection( &mscms_handle_cs ); - return NULL; - } - return transformtable[index]; -} - -void release_transform( cmsHTRANSFORM 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].data) return (HPROFILE)(index + 1); - } - if (!profiletable) - { - p = calloc( count, sizeof(*p) ); - } - else - { - count = num_profile_handles * 2; - p = realloc( profiletable, count * sizeof(*p) ); - if (p) memset( p + num_profile_handles, 0, num_profile_handles * sizeof(*p) ); - } - 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; - profiletable[index] = *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) + index--; + if (handle_table[index] && handle_table[index]->type == type) { - DWORD written; - - if (SetFilePointer( profile->file, 0, NULL, FILE_BEGIN ) || - !WriteFile( profile->file, profile->data, profile->size, &written, NULL ) || - written != profile->size) - { - ERR( "Unable to write color profile\n" ); - } + obj = handle_table[index]; + InterlockedIncrement( &obj->refs ); } - CloseHandle( profile->file ); } - if (profile->cmsprofile) cmsCloseProfile( profile->cmsprofile ); - free( profile->data ); - - memset( profile, 0, sizeof(struct profile) ); - LeaveCriticalSection( &mscms_handle_cs ); - return TRUE; + + TRACE( "handle %p -> %p\n", handle, obj ); + return obj; } -static HTRANSFORM alloc_transform_handle( void ) +void release_object( struct object *obj ) { - DWORD_PTR index; - cmsHTRANSFORM *p; - unsigned int count = 128; - - for (index = 0; index < num_transform_handles; index++) + ULONG refs = InterlockedDecrement( &obj->refs ); + if (!refs) { - if (!transformtable[index]) return (HTRANSFORM)(index + 1); + if (obj->close) obj->close( obj ); + TRACE( "destroying object %p\n", obj ); + free( obj ); } - if (!transformtable) - { - p = calloc( count, sizeof(*p) ); - } - else - { - count = num_transform_handles * 2; - p = realloc( transformtable, count * sizeof(*p) ); - if (p) memset( p + num_transform_handles, 0, num_transform_handles * sizeof(*p) ); - } - if (!p) return NULL; - - transformtable = p; - num_transform_handles = count; - - return (HTRANSFORM)(index + 1); } -HTRANSFORM create_transform( cmsHTRANSFORM transform ) +#define HANDLE_TABLE_SIZE 4 +HANDLE alloc_handle( struct object *obj ) { - HTRANSFORM handle; + struct object **ptr; + ULONG_PTR index, count; EnterCriticalSection( &mscms_handle_cs ); - - if ((handle = alloc_transform_handle())) + if (!max_handles) { - DWORD_PTR index = (DWORD_PTR)handle - 1; - transformtable[index] = transform; + count = HANDLE_TABLE_SIZE; + if (!(ptr = calloc( 1, sizeof(*ptr) * count ))) + { + LeaveCriticalSection( &mscms_handle_cs ); + return 0; + } + handle_table = ptr; + max_handles = count; } + if (max_handles == next_handle) + { + size_t new_size, old_size = max_handles * sizeof(*ptr); + count = max_handles * 2; + new_size = count * sizeof(*ptr); + if (!(ptr = realloc( handle_table, new_size ))) + { + LeaveCriticalSection( &mscms_handle_cs ); + return 0; + } + memset( (char *)ptr + old_size, 0, new_size - old_size ); + handle_table = ptr; + max_handles = count; + } + index = next_handle; + if (handle_table[index]) ERR( "handle isn't free but should be\n" ); + + handle_table[index] = obj; + InterlockedIncrement( &obj->refs ); + while (next_handle < max_handles && handle_table[next_handle]) next_handle++; + LeaveCriticalSection( &mscms_handle_cs ); - return handle; + TRACE( "object %p -> %Ix\n", obj, index + 1 ); + return (HANDLE)(index + 1); } -BOOL close_transform( HTRANSFORM handle ) +void free_handle( HANDLE handle ) { - DWORD_PTR index; - cmsHTRANSFORM transform; + struct object *obj = NULL; + ULONG_PTR index = (ULONG_PTR)handle; EnterCriticalSection( &mscms_handle_cs ); - - index = (DWORD_PTR)handle - 1; - if (index > num_transform_handles) + if (index > 0 && index <= max_handles) { - LeaveCriticalSection( &mscms_handle_cs ); - return FALSE; + index--; + if (handle_table[index]) + { + obj = handle_table[index]; + TRACE( "destroying handle %p for object %p\n", handle, obj ); + handle_table[index] = NULL; + } } - transform = transformtable[index]; - transformtable[index] = 0; - cmsDeleteTransform( transform ); - LeaveCriticalSection( &mscms_handle_cs ); - return TRUE; + + if (obj) release_object( obj ); + + EnterCriticalSection( &mscms_handle_cs ); + if (next_handle > index && !handle_table[index]) next_handle = index; + LeaveCriticalSection( &mscms_handle_cs ); } diff --git a/dlls/mscms/mscms_main.c b/dlls/mscms/mscms_main.c index 8c7e7c9e498..c8592405126 100644 --- a/dlls/mscms/mscms_main.c +++ b/dlls/mscms/mscms_main.c @@ -49,7 +49,6 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, void *reserved ) break; case DLL_PROCESS_DETACH: if (reserved) break; - free_handle_tables(); break; } return TRUE; diff --git a/dlls/mscms/mscms_priv.h b/dlls/mscms/mscms_priv.h index 29895fb8ae8..c32b5dc6158 100644 --- a/dlls/mscms/mscms_priv.h +++ b/dlls/mscms/mscms_priv.h @@ -27,28 +27,40 @@ #include -struct profile +enum object_type { - HANDLE file; - DWORD access; - char *data; - DWORD size; - cmsHPROFILE cmsprofile; + OBJECT_TYPE_PROFILE, + OBJECT_TYPE_TRANSFORM, }; -extern HPROFILE create_profile( struct profile * ) DECLSPEC_HIDDEN; -extern BOOL close_profile( HPROFILE ) DECLSPEC_HIDDEN; +struct object +{ + enum object_type type; + LONG refs; + void (*close)( struct object * ); +}; -extern HTRANSFORM create_transform( cmsHTRANSFORM ) DECLSPEC_HIDDEN; -extern BOOL close_transform( HTRANSFORM ) DECLSPEC_HIDDEN; +struct profile +{ + struct object hdr; + HANDLE file; + DWORD access; + char *data; + DWORD size; + cmsHPROFILE cmsprofile; +}; -struct profile *grab_profile( HPROFILE ) DECLSPEC_HIDDEN; -cmsHTRANSFORM grab_transform( HTRANSFORM ) DECLSPEC_HIDDEN; +struct transform +{ + struct object hdr; + cmsHTRANSFORM cmstransform; +}; -void release_profile( struct profile * ) DECLSPEC_HIDDEN; -void release_transform( cmsHTRANSFORM ) DECLSPEC_HIDDEN; +extern HANDLE alloc_handle( struct object *obj ) DECLSPEC_HIDDEN; +extern void free_handle( HANDLE ) DECLSPEC_HIDDEN; -extern void free_handle_tables( void ) DECLSPEC_HIDDEN; +struct object *grab_object( HANDLE, enum object_type ) DECLSPEC_HIDDEN; +void release_object( struct object * ) DECLSPEC_HIDDEN; struct tag_entry { diff --git a/dlls/mscms/profile.c b/dlls/mscms/profile.c index b23ad5bbe10..9c4b6be8342 100644 --- a/dlls/mscms/profile.c +++ b/dlls/mscms/profile.c @@ -323,7 +323,7 @@ BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PVOID buffer, PBOOL ref ) { BOOL ret; - struct profile *profile = grab_profile( handle ); + struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE ); TRACE( "( %p, %#lx, %lu, %p, %p, %p )\n", handle, type, offset, size, buffer, ref ); @@ -331,11 +331,11 @@ BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, if (!size || !ref) { - release_profile( profile ); + release_object( &profile->hdr ); return FALSE; } ret = get_tag_data( profile, type, offset, buffer, size, ref ); - release_profile( profile ); + release_object( &profile->hdr ); return ret; } @@ -360,7 +360,7 @@ BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE type ) { BOOL ret; - struct profile *profile = grab_profile( handle ); + struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE ); struct tag_entry tag; TRACE( "( %p, %lu, %p )\n", handle, index, type ); @@ -369,11 +369,11 @@ BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE ty if (!type) { - release_profile( profile ); + release_object( &profile->hdr ); return FALSE; } if ((ret = get_tag_entry( profile, index, &tag ))) *type = tag.sig; - release_profile( profile ); + release_object( &profile->hdr ); return ret; } @@ -397,7 +397,7 @@ BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE ty */ BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD size ) { - struct profile *profile = grab_profile( handle ); + struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE ); PROFILEHEADER header; TRACE( "( %p, %p, %p )\n", handle, buffer, size ); @@ -406,7 +406,7 @@ BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD siz if (!size) { - release_profile( profile ); + release_object( &profile->hdr ); return FALSE; } get_profile_header( profile, &header ); @@ -414,7 +414,7 @@ BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD siz if (!buffer || header.phSize > *size) { *size = header.phSize; - release_profile( profile ); + release_object( &profile->hdr ); return FALSE; } @@ -422,7 +422,7 @@ BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD siz memcpy( buffer, profile->data, profile->size ); *size = profile->size; - release_profile( profile ); + release_object( &profile->hdr ); return TRUE; } @@ -444,7 +444,7 @@ BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD siz */ BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header ) { - struct profile *profile = grab_profile( handle ); + struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE ); TRACE( "( %p, %p )\n", handle, header ); @@ -452,11 +452,11 @@ BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header ) if (!header) { - release_profile( profile ); + release_object( &profile->hdr ); return FALSE; } get_profile_header( profile, header ); - release_profile( profile ); + release_object( &profile->hdr ); return TRUE; } @@ -476,7 +476,7 @@ BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header ) */ BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count ) { - struct profile *profile = grab_profile( handle ); + struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE ); TRACE( "( %p, %p )\n", handle, count ); @@ -484,11 +484,11 @@ BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count ) if (!count) { - release_profile( profile ); + release_object( &profile->hdr ); return FALSE; } *count = get_tag_count( profile ); - release_profile( profile ); + release_object( &profile->hdr ); return TRUE; } @@ -1058,7 +1058,7 @@ BOOL WINAPI InstallColorProfileW( PCWSTR machine, PCWSTR profile ) */ BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL present ) { - struct profile *profile = grab_profile( handle ); + struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE ); struct tag_entry tag; TRACE( "( %p, %#lx, %p )\n", handle, type, present ); @@ -1067,11 +1067,11 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL prese if (!present) { - release_profile( profile ); + release_object( &profile->hdr ); return FALSE; } *present = get_adjusted_tag( profile, type, &tag ); - release_profile( profile ); + release_object( &profile->hdr ); return TRUE; } @@ -1091,7 +1091,7 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL prese */ BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid ) { - struct profile *profile = grab_profile( handle ); + struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE ); TRACE( "( %p, %p )\n", handle, valid ); @@ -1099,11 +1099,11 @@ BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid ) if (!valid) { - release_profile( profile ); + release_object( &profile->hdr ); return FALSE; } *valid = !!profile->data; - release_profile( profile ); + release_object( &profile->hdr ); return *valid; } @@ -1128,7 +1128,7 @@ BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PVOID buffer ) { BOOL ret; - struct profile *profile = grab_profile( handle ); + struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE ); TRACE( "( %p, %#lx, %lu, %p, %p )\n", handle, type, offset, size, buffer ); @@ -1136,11 +1136,11 @@ BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, if (!size || !buffer || !(profile->access & PROFILE_READWRITE)) { - release_profile( profile ); + release_object( &profile->hdr ); return FALSE; } ret = set_tag_data( profile, type, offset, buffer, size ); - release_profile( profile ); + release_object( &profile->hdr ); return ret; } @@ -1159,7 +1159,7 @@ BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, */ BOOL WINAPI SetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header ) { - struct profile *profile = grab_profile( handle ); + struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE ); TRACE( "( %p, %p )\n", handle, header ); @@ -1167,11 +1167,11 @@ BOOL WINAPI SetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header ) if (!header || !(profile->access & PROFILE_READWRITE)) { - release_profile( profile ); + release_object( &profile->hdr ); return FALSE; } set_profile_header( profile, header ); - release_profile( profile ); + release_object( &profile->hdr ); return TRUE; } @@ -1261,6 +1261,28 @@ HPROFILE WINAPI OpenColorProfileA( PPROFILE profile, DWORD access, DWORD sharing return handle; } +void close_profile( struct object *obj ) +{ + struct profile *profile = (struct profile *)obj; + + if (profile->file != INVALID_HANDLE_VALUE) + { + if (profile->access & PROFILE_READWRITE) + { + DWORD count; + if (SetFilePointer( profile->file, 0, NULL, FILE_BEGIN ) || + !WriteFile( profile->file, profile->data, profile->size, &count, NULL ) || count != profile->size) + { + ERR( "Unable to write color profile\n" ); + } + } + CloseHandle( profile->file ); + } + + if (profile->cmsprofile) cmsCloseProfile( profile->cmsprofile ); + free( profile->data ); +} + /****************************************************************************** * OpenColorProfileW [MSCMS.@] * @@ -1285,8 +1307,8 @@ HPROFILE WINAPI OpenColorProfileA( PPROFILE profile, DWORD access, DWORD sharing */ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation ) { - struct profile prof; - HPROFILE hprof; + struct profile *prof; + HPROFILE ret; cmsHPROFILE cmsprofile; char *data = NULL; HANDLE handle = INVALID_HANDLE_VALUE; @@ -1377,13 +1399,18 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing return NULL; } - prof.file = handle; - prof.access = access; - prof.data = data; - prof.size = size; - prof.cmsprofile = cmsprofile; - - if ((hprof = create_profile( &prof ))) return hprof; + if ((prof = calloc( 1, sizeof(*prof) ))) + { + prof->hdr.type = OBJECT_TYPE_PROFILE; + prof->hdr.close = close_profile; + prof->file = handle; + prof->access = access; + prof->data = data; + prof->size = size; + prof->cmsprofile = cmsprofile; + if ((ret = alloc_handle( &prof->hdr ))) return ret; + free( prof ); + } cmsCloseProfile( cmsprofile ); free( data ); @@ -1403,10 +1430,16 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing * Success: TRUE * Failure: FALSE */ -BOOL WINAPI CloseColorProfile( HPROFILE profile ) +BOOL WINAPI CloseColorProfile( HPROFILE handle ) { - TRACE( "( %p )\n", profile ); - return close_profile( profile ); + struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE ); + + TRACE( "( %p )\n", handle ); + + if (!profile) return FALSE; + free_handle( handle ); + release_object( &profile->hdr ); + return TRUE; } /****************************************************************************** diff --git a/dlls/mscms/transform.c b/dlls/mscms/transform.c index 22901ad721c..f02b8442579 100644 --- a/dlls/mscms/transform.c +++ b/dlls/mscms/transform.c @@ -19,6 +19,7 @@ */ #include +#include #include "windef.h" #include "winbase.h" @@ -103,6 +104,12 @@ HTRANSFORM WINAPI CreateColorTransformA( LPLOGCOLORSPACEA space, HPROFILE dest, return CreateColorTransformW( &spaceW, dest, target, flags ); } +static void close_transform( struct object *obj ) +{ + struct transform *transform = (struct transform *)obj; + if (transform->cmstransform) cmsDeleteTransform( transform->cmstransform ); +} + /****************************************************************************** * CreateColorTransformW [MSCMS.@] * @@ -121,7 +128,8 @@ HTRANSFORM WINAPI CreateColorTransformA( LPLOGCOLORSPACEA space, HPROFILE dest, HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest, HPROFILE target, DWORD flags ) { HTRANSFORM ret = NULL; - cmsHTRANSFORM transform; + struct transform *transform; + cmsHTRANSFORM cmstransform; struct profile *dst, *tgt = NULL; DWORD proofing = 0; cmsHPROFILE input; @@ -129,11 +137,10 @@ HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest, TRACE( "( %p, %p, %p, %#lx )\n", space, dest, target, flags ); - if (!space || !(dst = grab_profile( dest ))) return FALSE; - - if (target && !(tgt = grab_profile( target ))) + if (!space || !(dst = (struct profile *)grab_object( dest, OBJECT_TYPE_PROFILE ))) return FALSE; + if (target && !(tgt = (struct profile *)grab_object( target, OBJECT_TYPE_PROFILE ))) { - release_profile( dst ); + release_object( &dst->hdr ); return FALSE; } intent = space->lcsIntent > 3 ? INTENT_PERCEPTUAL : space->lcsIntent; @@ -144,19 +151,25 @@ HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest, input = cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */ if (target) proofing = cmsFLAGS_SOFTPROOFING; - transform = cmsCreateProofingTransform( input, 0, dst->cmsprofile, 0, tgt ? tgt->cmsprofile : NULL, - intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing ); - if (!transform) + cmstransform = cmsCreateProofingTransform( input, 0, dst->cmsprofile, 0, tgt ? tgt->cmsprofile : NULL, + intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing ); + if (!cmstransform) { - if (tgt) release_profile( tgt ); - release_profile( dst ); + if (tgt) release_object( &tgt->hdr ); + release_object( &dst->hdr ); return FALSE; } - ret = create_transform( transform ); + if ((transform = calloc( 1, sizeof(*transform) ))) + { + transform->hdr.type = OBJECT_TYPE_TRANSFORM; + transform->hdr.close = close_transform; + transform->cmstransform = cmstransform; + if (!(ret = alloc_handle( &transform->hdr ))) free( transform ); + } - if (tgt) release_profile( tgt ); - release_profile( dst ); + if (tgt) release_object( &tgt->hdr ); + release_object( &dst->hdr ); return ret; } @@ -181,7 +194,8 @@ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofil { HTRANSFORM ret = NULL; cmsHPROFILE cmsprofiles[2]; - cmsHTRANSFORM transform; + cmsHTRANSFORM cmstransform; + struct transform *transform; struct profile *profile0, *profile1; TRACE( "( %p, %#lx, %p, %lu, %#lx, %#lx )\n", profiles, nprofiles, intents, nintents, flags, cmm ); @@ -194,23 +208,34 @@ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofil return NULL; } - profile0 = grab_profile( profiles[0] ); + profile0 = (struct profile *)grab_object( profiles[0], OBJECT_TYPE_PROFILE ); if (!profile0) return NULL; - profile1 = grab_profile( profiles[1] ); + profile1 = (struct profile *)grab_object( profiles[1], OBJECT_TYPE_PROFILE ); if (!profile1) { - release_profile( profile0 ); + release_object( &profile0->hdr ); return NULL; } cmsprofiles[0] = profile0->cmsprofile; cmsprofiles[1] = profile1->cmsprofile; + if (!(cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, 0, 0, *intents, 0 ))) + { + release_object( &profile0->hdr ); + release_object( &profile1->hdr ); + return FALSE; + } - transform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, 0, 0, *intents, 0 ); - if (transform) ret = create_transform( transform ); + if ((transform = calloc( 1, sizeof(*transform) ))) + { + transform->hdr.type = OBJECT_TYPE_TRANSFORM; + transform->hdr.close = close_transform; + transform->cmstransform = cmstransform; + if (!(ret = alloc_handle( &transform->hdr ))) free( transform ); + } - release_profile( profile0 ); - release_profile( profile1 ); + release_object( &profile0->hdr ); + release_object( &profile1->hdr ); return ret; } @@ -228,9 +253,14 @@ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofil */ BOOL WINAPI DeleteColorTransform( HTRANSFORM handle ) { + struct transform *transform = (struct transform *)grab_object( handle, OBJECT_TYPE_TRANSFORM ); + TRACE( "( %p )\n", handle ); - return close_transform( handle ); + if (!transform) return FALSE; + free_handle( handle ); + release_object( &transform->hdr ); + return TRUE; } /****************************************************************************** @@ -260,16 +290,16 @@ BOOL WINAPI TranslateBitmapBits( HTRANSFORM handle, PVOID srcbits, BMFORMAT inpu DWORD outputstride, PBMCALLBACKFN callback, ULONG data ) { BOOL ret; - cmsHTRANSFORM transform = grab_transform( handle ); + struct transform *transform = (struct transform *)grab_object( handle, OBJECT_TYPE_TRANSFORM ); TRACE( "( %p, %p, %#x, %lu, %lu, %lu, %p, %#x, %lu, %p, %#lx )\n", handle, srcbits, input, width, height, inputstride, destbits, output, outputstride, callback, data ); if (!transform) return FALSE; - ret = cmsChangeBuffersFormat( transform, from_bmformat(input), from_bmformat(output) ); - if (ret) cmsDoTransform( transform, srcbits, destbits, width * height ); - release_transform( transform ); + ret = cmsChangeBuffersFormat( transform->cmstransform, from_bmformat(input), from_bmformat(output) ); + if (ret) cmsDoTransform( transform->cmstransform, srcbits, destbits, width * height ); + release_object( &transform->hdr ); return ret; } @@ -295,16 +325,16 @@ BOOL WINAPI TranslateColors( HTRANSFORM handle, PCOLOR in, DWORD count, { BOOL ret; unsigned int i; - cmsHTRANSFORM transform = grab_transform( handle ); + struct transform *transform = (struct transform *)grab_object( handle, OBJECT_TYPE_TRANSFORM ); TRACE( "( %p, %p, %lu, %d, %p, %d )\n", handle, in, count, input_type, out, output_type ); if (!transform) return FALSE; - ret = cmsChangeBuffersFormat( transform, from_type(input_type), from_type(output_type) ); + ret = cmsChangeBuffersFormat( transform->cmstransform, from_type(input_type), from_type(output_type) ); if (ret) - for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i], &out[i], 1 ); + for (i = 0; i < count; i++) cmsDoTransform( transform->cmstransform, &in[i], &out[i], 1 ); - release_transform( transform ); + release_object( &transform->hdr ); return ret; }