1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-08 03:45:57 +00:00

mscms: Merge the profile and transform handle tables.

This commit is contained in:
Hans Leidekker 2022-06-16 17:23:40 +02:00 committed by Alexandre Julliard
parent 8a56c4dbba
commit ebcb18d418
5 changed files with 235 additions and 261 deletions

View File

@ -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 );
}

View File

@ -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;

View File

@ -27,28 +27,40 @@
#include <lcms2.h>
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
{

View File

@ -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;
}
/******************************************************************************

View File

@ -19,6 +19,7 @@
*/
#include <stdarg.h>
#include <stdlib.h>
#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;
}