Commit ebcb18d4 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

mscms: Merge the profile and transform handle tables.

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