mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 09:34:09 +00:00
mscms: Merge the profile and transform handle tables.
This commit is contained in:
parent
8a56c4dbba
commit
ebcb18d418
|
@ -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;
|
||||
index--;
|
||||
if (handle_table[index] && handle_table[index]->type == type)
|
||||
{
|
||||
obj = handle_table[index];
|
||||
InterlockedIncrement( &obj->refs );
|
||||
}
|
||||
}
|
||||
return &profiletable[index];
|
||||
}
|
||||
|
||||
void release_profile( struct profile *profile )
|
||||
{
|
||||
LeaveCriticalSection( &mscms_handle_cs );
|
||||
|
||||
TRACE( "handle %p -> %p\n", handle, obj );
|
||||
return obj;
|
||||
}
|
||||
|
||||
cmsHTRANSFORM grab_transform( HTRANSFORM handle )
|
||||
void release_object( struct object *obj )
|
||||
{
|
||||
DWORD_PTR index;
|
||||
ULONG refs = InterlockedDecrement( &obj->refs );
|
||||
if (!refs)
|
||||
{
|
||||
if (obj->close) obj->close( obj );
|
||||
TRACE( "destroying object %p\n", obj );
|
||||
free( obj );
|
||||
}
|
||||
}
|
||||
|
||||
#define HANDLE_TABLE_SIZE 4
|
||||
HANDLE alloc_handle( struct object *obj )
|
||||
{
|
||||
struct object **ptr;
|
||||
ULONG_PTR index, count;
|
||||
|
||||
EnterCriticalSection( &mscms_handle_cs );
|
||||
|
||||
index = (DWORD_PTR)handle - 1;
|
||||
if (index > num_transform_handles)
|
||||
if (!max_handles)
|
||||
{
|
||||
count = HANDLE_TABLE_SIZE;
|
||||
if (!(ptr = calloc( 1, sizeof(*ptr) * count )))
|
||||
{
|
||||
LeaveCriticalSection( &mscms_handle_cs );
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
return transformtable[index];
|
||||
}
|
||||
|
||||
void release_transform( cmsHTRANSFORM transform )
|
||||
{
|
||||
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 );
|
||||
TRACE( "object %p -> %Ix\n", obj, index + 1 );
|
||||
return (HANDLE)(index + 1);
|
||||
}
|
||||
|
||||
static HPROFILE alloc_profile_handle( void )
|
||||
void free_handle( HANDLE handle )
|
||||
{
|
||||
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;
|
||||
struct object *obj = NULL;
|
||||
ULONG_PTR index = (ULONG_PTR)handle;
|
||||
|
||||
EnterCriticalSection( &mscms_handle_cs );
|
||||
|
||||
if ((handle = alloc_profile_handle()))
|
||||
if (index > 0 && index <= max_handles)
|
||||
{
|
||||
DWORD_PTR index = (DWORD_PTR)handle - 1;
|
||||
profiletable[index] = *profile;
|
||||
index--;
|
||||
if (handle_table[index])
|
||||
{
|
||||
obj = handle_table[index];
|
||||
TRACE( "destroying handle %p for object %p\n", handle, obj );
|
||||
handle_table[index] = NULL;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection( &mscms_handle_cs );
|
||||
return handle;
|
||||
}
|
||||
|
||||
BOOL close_profile( HPROFILE handle )
|
||||
{
|
||||
DWORD_PTR index;
|
||||
struct profile *profile;
|
||||
if (obj) release_object( obj );
|
||||
|
||||
EnterCriticalSection( &mscms_handle_cs );
|
||||
|
||||
index = (DWORD_PTR)handle - 1;
|
||||
if (index > num_profile_handles)
|
||||
{
|
||||
if (next_handle > index && !handle_table[index]) next_handle = index;
|
||||
LeaveCriticalSection( &mscms_handle_cs );
|
||||
return FALSE;
|
||||
}
|
||||
profile = &profiletable[index];
|
||||
|
||||
if (profile->file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (profile->access & PROFILE_READWRITE)
|
||||
{
|
||||
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" );
|
||||
}
|
||||
}
|
||||
CloseHandle( profile->file );
|
||||
}
|
||||
if (profile->cmsprofile) cmsCloseProfile( profile->cmsprofile );
|
||||
free( profile->data );
|
||||
|
||||
memset( profile, 0, sizeof(struct profile) );
|
||||
|
||||
LeaveCriticalSection( &mscms_handle_cs );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static HTRANSFORM alloc_transform_handle( void )
|
||||
{
|
||||
DWORD_PTR index;
|
||||
cmsHTRANSFORM *p;
|
||||
unsigned int count = 128;
|
||||
|
||||
for (index = 0; index < num_transform_handles; index++)
|
||||
{
|
||||
if (!transformtable[index]) return (HTRANSFORM)(index + 1);
|
||||
}
|
||||
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 )
|
||||
{
|
||||
HTRANSFORM handle;
|
||||
|
||||
EnterCriticalSection( &mscms_handle_cs );
|
||||
|
||||
if ((handle = alloc_transform_handle()))
|
||||
{
|
||||
DWORD_PTR index = (DWORD_PTR)handle - 1;
|
||||
transformtable[index] = transform;
|
||||
}
|
||||
LeaveCriticalSection( &mscms_handle_cs );
|
||||
return handle;
|
||||
}
|
||||
|
||||
BOOL close_transform( HTRANSFORM handle )
|
||||
{
|
||||
DWORD_PTR index;
|
||||
cmsHTRANSFORM transform;
|
||||
|
||||
EnterCriticalSection( &mscms_handle_cs );
|
||||
|
||||
index = (DWORD_PTR)handle - 1;
|
||||
if (index > num_transform_handles)
|
||||
{
|
||||
LeaveCriticalSection( &mscms_handle_cs );
|
||||
return FALSE;
|
||||
}
|
||||
transform = transformtable[index];
|
||||
transformtable[index] = 0;
|
||||
cmsDeleteTransform( transform );
|
||||
|
||||
LeaveCriticalSection( &mscms_handle_cs );
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -27,8 +27,22 @@
|
|||
|
||||
#include <lcms2.h>
|
||||
|
||||
enum object_type
|
||||
{
|
||||
OBJECT_TYPE_PROFILE,
|
||||
OBJECT_TYPE_TRANSFORM,
|
||||
};
|
||||
|
||||
struct object
|
||||
{
|
||||
enum object_type type;
|
||||
LONG refs;
|
||||
void (*close)( struct object * );
|
||||
};
|
||||
|
||||
struct profile
|
||||
{
|
||||
struct object hdr;
|
||||
HANDLE file;
|
||||
DWORD access;
|
||||
char *data;
|
||||
|
@ -36,19 +50,17 @@ struct profile
|
|||
cmsHPROFILE cmsprofile;
|
||||
};
|
||||
|
||||
extern HPROFILE create_profile( struct profile * ) DECLSPEC_HIDDEN;
|
||||
extern BOOL close_profile( HPROFILE ) DECLSPEC_HIDDEN;
|
||||
struct transform
|
||||
{
|
||||
struct object hdr;
|
||||
cmsHTRANSFORM cmstransform;
|
||||
};
|
||||
|
||||
extern HTRANSFORM create_transform( cmsHTRANSFORM ) DECLSPEC_HIDDEN;
|
||||
extern BOOL close_transform( HTRANSFORM ) DECLSPEC_HIDDEN;
|
||||
extern HANDLE alloc_handle( struct object *obj ) DECLSPEC_HIDDEN;
|
||||
extern void free_handle( HANDLE ) DECLSPEC_HIDDEN;
|
||||
|
||||
struct profile *grab_profile( HPROFILE ) DECLSPEC_HIDDEN;
|
||||
cmsHTRANSFORM grab_transform( HTRANSFORM ) DECLSPEC_HIDDEN;
|
||||
|
||||
void release_profile( struct profile * ) DECLSPEC_HIDDEN;
|
||||
void release_transform( cmsHTRANSFORM ) 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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -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,
|
||||
cmstransform = cmsCreateProofingTransform( input, 0, dst->cmsprofile, 0, tgt ? tgt->cmsprofile : NULL,
|
||||
intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing );
|
||||
if (!transform)
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue